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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24727435/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 14:30:51  来源:igfitidea点击:

Checking range of List in forEach lambda loop Java 8

javaforeachlambdajava-8

提问by

I want to learn how I can check the range of a list in java 8.

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

For example,

例如,

My Code:

我的代码:

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

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

My out come is

我出来的是

    Peter,James,Bart,

but I want to know how I can get rid of the last ,

但我想知道我怎样才能摆脱最后一个,

Note: I know I must use filter here , yet I do not know how and I know there is another way to solve this which is as follows

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

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

yet I want to know how to check the range and get rid of , in my first code.

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

采纳答案by Stuart Marks

There's no direct way to get the index of a stream item while you're processing the items themselves. There are several alternatives, though.

在处理项目本身时,没有直接的方法来获取流项目的索引。不过,有几种选择。

One way is to run the stream over the indexes and then get the elements from the list. For each element index it maps ito the i'th element and appends a "," for all indexes except the last:

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

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

A second, more concise variation is to special case the first element instead of the last one:

第二个更简洁的变体是对第一个元素而不是最后一个元素进行特殊处理:

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

A third way is to use the particular reduceoperation that is applied "between" each two adjacent elements. The problem with this technique is that it does O(n^2) copying, which will become quite slow for large streams.

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

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

A fourth way is to special-case the last element by limiting the stream to length n-1. This requires a separate print statement, which isn't as pretty though:

第四种方法是通过将流限制为长度 n-1 来对最后一个元素进行特殊处理。这需要一个单独的打印语句,虽然它不是那么漂亮:

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

A fifth way is similar to the above, special-casing the first element instead of the last:

第五种方式与上述类似,特殊情况下第一个元素而不是最后一个:

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

Really, though the point of the joiningcollector is to do this ugly and irritating special-casing for you, so you don't have to do it yourself.

真的,虽然joining收藏家的目的是为你做这个丑陋而刺激的特殊外壳,所以你不必自己做。

回答by specializt

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

This will reduce the stream to the strings which are NOT equal to Bart

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

And this will print the last value of a map :

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

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)));

回答by GingerHead

What about:

关于什么:

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

回答by Alex

You could do this:

你可以这样做:

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

flatMapreplaces each element of the original stream with the elements in the streams returned from the mapping function.

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

So if your stream was originally

所以如果你的流最初是

"Peter" - "James" - "Bart"

The above mapping function changes it to

上面的映射函数将其更改为

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

Then the limitremoves the last ","by shortening the stream to be at most the length of the value that is passed to it, which in this case is the size of the stream - 1. The size of the stream was 2 * the size of the list before limitbecause flatMapdoubled it's length.

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

Note that this will throw an IllegalArgumentExceptionif the list is empty, because the value passed to limitwill be -1. You should check for this first if that is a possibility.

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

回答by NiNa

We can also try using limit and skip methods of stream API to this problem. Here is my try to this problem.

我们也可以尝试使用stream 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 is a List of Integers having values 2,4,7,14. The output will look like 2,4,7,14

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

回答by Lance

try this,

尝试这个,

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