检查forEach lambda循环Java 8中List的范围

时间:2014-07-13 22:22:39

标签: java foreach lambda java-8

我想学习如何检查java 8中列表的范围。

例如,

我的代码:

    List<String> objList = new ArrayList<>();
    objList.add("Peter");
    objList.add("James");
    objList.add("Bart");

    objList.stream().map((s) -> s + ",").forEach(System.out::print);

我的出来是

    Peter,James,Bart,

但我想知道如何摆脱最后一次,

注意:我知道我必须在这里使用过滤器,但我不知道如何以及我知道还有另一种解决方法,如下所示

String result = objList.stream()
    .map(Person::getFirstName)
    .collect(Collectors.joining(","));

但我想知道如何检查范围并摆脱我的第一个代码。

6 个答案:

答案 0 :(得分:4)

你可以这样做:

objList.stream().flatMap((s) -> Stream.of(s, ','))
        .limit(objList.size() * 2 - 1).forEach(System.out::print);

flatMap用映射函数返回的流中的元素替换原始流的每个元素。

因此,如果您的信息流最初是

"Peter" - "James" - "Bart"

上述映射功能将其更改为

"Peter" - "," - "James" - "," - "Bart" - ","

然后limit删除最后一个",",将流缩短为最多传递给它的值的长度,在这种情况下是流的大小 - 1。流的大小是limit之前列表大小的2 *,因为flatMap加倍了它的长度。

请注意,如果列表为空,这将抛出IllegalArgumentException,因为传递给limit的值将为-1。如果可能的话,你应该先检查一下。

答案 1 :(得分:4)

在您自己处理项目时,无法直接获取流项目的索引。但是,有几种选择。

一种方法是在索引上运行流,然后从列表中获取元素。对于每个元素索引,它将i映射到第i个元素,并为除最后一个之外的所有索引附加“,”:

IntStream.range(0, objList.size())
    .mapToObj(i -> objList.get(i) + (i < objList.size()-1 ? "," : ""))
    .forEach(System.out::print);

第二个更简洁的变化是特殊情况下的第一个元素而不是最后一个元素:

IntStream.range(0, objList.size())
    .mapToObj(i -> (i > 0 ? "," : "") + objList.get(i))
    .forEach(System.out::print);

第三种方法是使用在每两个相邻元素之间“应用”的特定reduce操作。这种技术的问题在于它进行O(n ^ 2)复制,对于大流来说这将变得非常慢。

System.out.println(objList.stream().reduce((a,b) -> a + "," + b).get());

第四种方法是通过将流限制为长度n-1来特殊情况下最后一个元素。这需要一个单独的print语句,虽然不是很漂亮:

objList.stream()
    .limit(objList.size()-1)
    .map(s -> s + ",")
    .forEach(System.out::print);
System.out.print(objList.get(objList.size()-1));

第五种方式与上面类似,特殊套管是第一个元素而不是最后一个:

System.out.print(objList.get(0));
objList.stream()
    .skip(1)
    .map(s -> "," + s)
    .forEach(System.out::print);

真的,虽然joining收藏家的观点是要为你做这个丑陋而刺激性的特殊外壳,所以你不必亲自去做。

答案 2 :(得分:1)

怎么样:

String concat = objList.stream().reduce(",", String::concat);
System.out.println(concat);

答案 3 :(得分:0)

objList.stream().filter(s -> { return !s.equals("Bart") })

这会将流减少到不等于Bart的字符串

这将打印地图的最后一个值:

Map<Integer, String> map = new HashMap<>();
map.put(0, "a");
map.put(1, "c");
map.put(2, "d");

Integer lastIndex = map.keySet().size() - 1;

Stream<String> lastValueStream = map.values().stream().filter(s -> s.equals(map.get(lastIndex)));

答案 4 :(得分:0)

我们也可以尝试使用流API的limit和skip方法来解决此问题。这是我对这个问题的尝试。

    returnData.stream().limit(returnData.size()-1).forEach(s->System.out.print(s+","));
    returnData.stream().skip(returnData.size()-1).forEach(s->System.out.print(s));

returnData是具有值2、4、7、14的整数列表。输出看起来像2,4,7,14

答案 5 :(得分:0)

尝试一下

int[] counter = new int[]{0};
objList.stream()
    .map(f -> (counter[0]++ > 0? "," : "") + f)
    .forEach(System.out::print);