使用Java 8更改List中元素的所有位置

时间:2017-05-30 09:29:22

标签: java collections java-8

我是Java的新手。我只想使用Java 8更改List中元素的所有位置。例如:

public static List<Integer> change(List<Integer> data){
    for (int i = 0; i < data.size(); i++) {
        Collections.swap(data, i, data.size()-1-i);
    }
    return data;
}

这是一个简单的例子,它只是反转列表。让我解释一下: 我有一个列表{1,3,4,5,3,7,8,9}&gt;&gt;我想改为{3,1,5,4,7,3,9,8}。

但我想在Java 8(Stream)中做到这一点。我的问题是:

1)如何获取流中的下一个元素?

2)当我用流遍历时,我可以使用自己的方法吗? (例如,我可以编写自己的交换方法吗?) - 喜欢:list.foreach(doSomething());

3)使用foreach时如何返回结果?

5 个答案:

答案 0 :(得分:3)

试试这个:

List<String> list = Arrays.asList("A", "B", "C", "D", "1", "2", "3");

    // shuffle or randomize
    Collections.shuffle(list);

答案 1 :(得分:0)

如果你想以这样的方式进行洗牌,那么之前就没有任何项目了,你可以简单地使用

Collections.reverse(list);

然后如果列表的长度为奇数,则交换第1项和中间项。通过这种方式,您的所有商品都将处于不同的索引之前。

答案 2 :(得分:0)

如果需要使用流

public static List<Integer> change2( List<Integer> data ) {

    return data.stream().collect( LinkedList::new, LinkedList::offerFirst, LinkedList::addAll );

}

使用LinkedList反转流以收集数据; offerFirst插入前面的下一个元素。

或使用自定义功能

final Random random = new Random();
return data.stream().collect(
    LinkedList::new,
    ( list, elem ) -> {
        int size = list.size();
        list.add( random.nextInt( size + 1 ), elem );
    },
    LinkedList::addAll
);

答案 3 :(得分:0)

您可以使用Streams提供的“forEach”。 说“a-&gt;”您将数据列表的每个元素映射到“a”,其中是列表的每个元素

这是最好的解决方案,如果你不想只是改组它们,而是对列表中的每个元素做更多的事情。

public static List<Integer> change(List<Integer> data){
    return data.stream().forEach(a-> "whatever you want to do with them").collect(Collectors.toList());
}

答案 4 :(得分:0)

一种方法是通过IntStream中的forEach和交换元素来推动您的列表:

public static List<Integer> change(List<Integer> data) {
    IntStream.iterate(0, i -> i + 2)
            .limit(data.size() / 2)
            .forEach(i -> Collections.swap(data, i, i + 1));
    return data;
}

您必须使用Stream.limit,以便流不是无限的。

但是,不鼓励使用Collections.swap来改变forEach中的列表,因为它有副作用。如果IntStream被声明为并行,则上面的代码将被破坏。理想情况下,流中使用的函数和使用者应该是无状态的,没有副作用,如java.util.stream package documentation中所建议的那样。

这是实现目标的另一种方式,同时也遵循建议:

public static List<Integer> changeCorrectly(List<Integer> data) {
    return IntStream.iterate(0, i -> i + 2)
            .limit(data.size() / 2)
            .flatMap(i -> IntStream.of(data.get(i + 1), data.get(i)))
            .boxed()
            .collect(Collectors.toList());
}

注意:我使用IntStream.flatMap返回IntStream个交换对,这对Integer列表中的unbox data元素有效。我立即将IntStream装箱到Stream<Integer>

避免这种拆箱/装箱的替代方法是:

public static List<Integer> changeCorrectly(List<Integer> data) {
    return IntStream.iterate(0, i -> i + 2)
            .limit(data.size() / 2)
            .mapToObj(i -> Stream.of(data.get(i + 1), data.get(i)))
            .flatMap(Function.identity())
            .collect(Collectors.toList());
}

最终评论:仅当data列表的大小均匀时才有效。当data列表具有奇数大小时,处理最后一个元素的添加留作练习。