如何将此代码转换为JAVA 8 Stream API?

时间:2017-04-11 12:14:20

标签: java list java-8 java-stream

我想使用Java 8 Stream将此while循环转换为等效代码,但我不知道如何同时传输List 从中删除元素。

private List<String> nameList = new ArrayList<>();

while (nameList.size() > 0) {
    String nameListFirstEntry = nameList.get(0);
    nameList.remove(0);
    setNameCombinations(nameListFirstEntry);
}

2 个答案:

答案 0 :(得分:6)

我想这会做

nameList.forEach(this::setNameCombinations);
nameList.clear();

如果您不再需要原始列表,您也可以改为创建一个新的空列表。

答案 1 :(得分:4)

因为List#remove(int)也返回了元素,你可以流式传输列表的元素通过流删除它们:

Stream.generate(() -> nameList.remove(0))
    .limit(nameList.size())
    .forEach(this::setNameCombinations);

此代码不会破坏任何“规则”。来自Stream#generate()的javadoc:

  

返回无限顺序无序流,其中每个元素由提供的供应商生成。这适用于生成恒定流,随机元素流等。

没有提及对如何供应商实施或必须没有副作用等的任何限制。供应商唯一的合同是供应。

对于那些怀疑这是“有效”的人,这里有一些使用100K元素的测试代码,表明确实保留了订单:

int size = 100000;
List<Integer> list0 = new ArrayList<>(size); // the reference list
IntStream.range(0, size).boxed().forEach(list0::add);
List<Integer> list1 = new ArrayList<>(list0); // will feed stream
List<Integer> list2 = new ArrayList<>(size);  // will consume stream

Stream.generate(() -> list1.remove(0))
        .limit(list1.size())
        .forEach(list2::add);

System.out.println(list0.equals(list2)); // always true