Java 8 Stream混合了两个元素 [英] Java 8 Stream mixing two elements

查看:570
本文介绍了Java 8 Stream混合了两个元素的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在数组列表中有许多Slot类型的对象。

I have a many objects of type Slot in an array list.

Slot class如下所示 -

Slot class is as shown below-

Slot{
   int start;
   int end;
}

让类型列表列表< Slot> 被称为 slots 。插槽根据开始时间排序。一个插槽的结束时间可能等于下一个插槽的开始时间,但它们永远不会重叠。

let the list of type List<Slot> be called slots. The slots are sorted based on start time. End time of one slot may be equal to start time of next slot, but they would never overlap.

有没有可能的方法可以使用这个列表迭代Java 8流,并结合两个插槽,如果一个的结束时间匹配下一个的开始时间并将它们输出到 ArrayList

Is there any possible way in which I can iterate over this list using Java 8 streams, and combine two slots if end time of one matches start time of next and output them into an ArrayList?

推荐答案

我的免费 StreamEx 库完全支持这种情况它增强了标准的Stream API。有一个 intervalMap 中间操作,它能够将几个相邻的流元素折叠到单个元素。这是完整的示例:

Such scenario is perfectly supported by my free StreamEx library which enhances standard Stream API. There's an intervalMap intermediate operation which is capable to collapse several adjacent stream elements to the single element. Here's complete example:

// Slot class and sample data are taken from @Andreas answer
List<Slot> slots = Arrays.asList(new Slot(3, 5), new Slot(5, 7), 
                new Slot(8, 10), new Slot(10, 11), new Slot(11, 13));

List<Slot> result = StreamEx.of(slots)
        .intervalMap((s1, s2) -> s1.end == s2.start,
                     (s1, s2) -> new Slot(s1.start, s2.end))
        .toList();
System.out.println(result);
// Output: [3-7, 8-13]

intervalMap 方法有两个参数。第一个是 BiPredicate 接受输入流中的两个相邻元素,如果必须合并则返回true(这里的条件是 s1.end == s2.start )。第二个参数是 BiFunction ,它从合并的系列中获取第一个和最后一个元素,并生成结果元素。

The intervalMap method takes two parameters. The first is a BiPredicate accepting two adjacent elements from the input stream and returns true if they must be merged (here the condition is s1.end == s2.start). The second parameter is a BiFunction which takes the first and the last elements from the merged series and produces the resulting element.

请注意,如果你有100个相邻的插槽应该组合成一个,这个解决方案不会创建100个中间对象(比如@ Misha的答案,这是然而,非常有趣的是,它跟踪系列中的第一个和最后一个插槽,立即忘记了中间部分。当然这个解决方案是并行友好的。如果您有数千个输入槽,使用 .parallel()可以提高性能。

Note that if you have, for example 100 adjacent slots which should be combined into one, this solution does not create 100 intermediate objects (like in @Misha's answer, which is nevertheless very interesting), it tracks first and last slot in the series immediately forgetting about intermediate onces. Of course this solution is parallel friendly. If you have many thousands of input slots, using .parallel() may improve the performance.

注意当前实现将重新创建 Slot ,即使它没有与任何东西合并。在这种情况下, BinaryOperator 会两次收到相同的 Slot 参数。如果你想优化这种情况,你可以进行额外的检查,如 s1 == s2? s1:...

Note that current implementation will recreate the Slot even if it's not merged with anything. In this case the BinaryOperator receives the same Slot parameter twice. If you want to optimize this case, you can make additional check like s1 == s2 ? s1 : ...:

List<Slot> result = StreamEx.of(slots)
        .intervalMap((s1, s2) -> s1.end == s2.start,
                     (s1, s2) -> s1 == s2 ? s1 : new Slot(s1.start, s2.end))
        .toList();

这篇关于Java 8 Stream混合了两个元素的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆