Java 8 Stream:如何将当前元素与下一个元素进行比较?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33705753/
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
Java 8 Stream: How to compare current element with next element?
提问by bhupen
How to get the next element from a List
using Java 8 Streams?
如何从List
使用 Java 8 Streams 中获取下一个元素?
If I am iterating over a List
, I want to compare current with next element of the list.
如果我正在迭代 a List
,我想将当前元素与列表的下一个元素进行比较。
Is it doable using Java 8 Stream?
使用 Java 8 Stream 是否可行?
回答by Tagir Valeev
My free StreamExlibrary allows you to process the pairs of the stream elements using additional pairMap
intermediate operation. Like this:
我的免费StreamEx库允许您使用额外的pairMap
中间操作处理流元素对。像这样:
StreamEx.of(input).pairMap((current, next) -> doSomethingWith(current, next));
Where input
is a Collection
, array or Stream
. For example, this way you can easily check whether input is sorted:
其中input
是Collection
,阵列或Stream
。例如,您可以通过这种方式轻松检查输入是否已排序:
boolean isSorted = StreamEx.of(input)
.pairMap((current, next) -> next.compareTo(current))
.allMatch(cmp -> cmp >= 0);
There's also forPairs
terminal operation which is a forEach
analog to all pairs of input elements:
还有forPairs
一个forEach
类似于所有输入元素对的终端操作:
StreamEx.of(input).forPairs((current, next) -> doSomethingWith(current, next));
These features work nicely with any stream source (either random access or not) and fully support the parallel streams.
这些功能可以很好地与任何流源(随机访问或非随机访问)配合使用,并完全支持并行流。
回答by Eran
One way is to generate an IntStream
of the indices, and fetch the List
elements by their index. This is only efficient if the List
supports random access (i.e. if your List
is a LinkedList
, it would be a bad idea, since list.get(i)
doesn't take constant time).
一种方法是生成一个IntStream
索引,并List
通过它们的索引获取元素。这仅在List
支持随机访问时才有效(即,如果您List
是LinkedList
,那将是一个坏主意,因为list.get(i)
不需要恒定时间)。
For example :
例如 :
IntStream.range(0,list.size()-1).forEach(i -> {
doSomething(list.get(i),list.get(i+1));
});
Another way is to store the last element in an array :
另一种方法是将最后一个元素存储在数组中:
List<Element> list = ...
Element[] arr = new Element[1];
list.stream().forEach(e -> {
if (arr[0] != null)
doSomething(arr[0],e);
arr[0]=e;
});
This will only work for sequential streams.
这仅适用于顺序流。
回答by Marc Dzaebel
Stream.reducecould be used, depending on the goal. As you said, you'd like to compare consecutive elements, the following would print "Same 3":
可以使用Stream.reduce,具体取决于目标。正如您所说,您想比较连续的元素,以下将打印“相同 3”:
Stream.of(1,2,3,3).reduce((a,b)->{
if(a==b) System.out.println("Same "+a);
return b; // will be "a" for next reduction
});
回答by Georg Moser
If you had a list of Integers for example and wanted to check if they are sorted ascending, you could do as follows:
例如,如果您有一个整数列表并想检查它们是否按升序排序,您可以执行以下操作:
@Test
public void test_listIsSorted() {
// create integer list for testing purposes: 0,1,2,3, .., 10
List<Integer> integerList = IntStream.range(0, 10)
.boxed()
.collect(Collectors.toList());
// stream list and compare item n with n+1
integerList.stream()
.reduce((integer1, integer2) -> {
assert integer1 < integer2 : "ordering must be ascending";
// return second value (which will be processed as "integer1" in the next iteration
return integer2;
});
}
This will compare pairs like: (0,1),(1,2),...
这将比较像:(0,1),(1,2),...
回答by walkeros
You always do one of following:
您始终执行以下操作之一:
- Convert your stream to a stream of elements containing "history" of last few elements of the stream
- Process your stream in such a way that currently processed element is considered to be "next" element and previously processed element is considered to be "current" element.
- 将您的流转换为包含流的最后几个元素的“历史”的元素流
- 以当前处理的元素被视为“下一个”元素而先前处理的元素被视为“当前”元素的方式处理您的流。
Implementations of both solutions can be seen in this thread: Is it possible to get next element in the Stream?
在此线程中可以看到这两种解决方案的实现:Is it possible to get next element in the Stream?
回答by Beezer
I had to do the same and compare the differences of the elements of a stream (originally an array). So I used a method as a parameter to the UnaryOperator that .map() expects as follows...and it worked for me without any special gizmo's:
我必须做同样的事情并比较流(最初是一个数组)的元素的差异。所以我使用了一个方法作为 .map() 期望如下的 UnaryOperator 的参数......它对我有用,没有任何特殊的小工具:
import java.util.Arrays;
class streamDiffUtil {
public static void main(String[] args) {
int[] elements = {1,2,5};
int result = Arrays.stream(elements)
.map(value -> calcMaxDiff(value, elements))
.max()
.getAsInt();
System.out.println(result);
}
private static int calcMaxDiff(int j, int[] elements) {
return Arrays.stream(elements)
.map(value -> Math.abs(j-value))
.max().getAsInt();
}
}
What would be nice is to know how the method calcMaxDiff equates to a UnaryIntOperator in the .map signature. That is a little beyond me. Hope this helps you.
最好知道 calcMaxDiff 方法如何等同于 .map 签名中的 UnaryIntOperator。这有点超出我的范围。希望这对你有帮助。