检查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
Checking range of List in forEach lambda loop Java 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 i
to 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 reduce
operation 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 joining
collector 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);
flatMap
replaces 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 limit
removes 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 limit
because flatMap
doubled it's length.
然后通过将流缩短到最多传递给它的值的长度来limit
删除最后一个","
,在这种情况下是流的大小 - 1。流的大小是 2 * 列表的大小之前limit
因为flatMap
它的长度翻了一番。
Note that this will throw an IllegalArgumentException
if the list is empty, because the value passed to limit
will 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);