java - 每天对 Java 8 Stream API 中的实体进行延迟排序?

标签 java java-8 java-stream

我有一个大型 Java 8 流 ( Stream<MyObject> ),其对象如下所示:

class MyObject {
   private String string;
   private Date timestamp;

   // Getters and setter removed from brevity 
}

我知道第 1 天的所有时间戳都将先于第 2 天的时间戳到达,但在每一天中,时间戳都可能乱序。我想对 MyObject 进行排序在 timestamp 中使用 Stream API 每天订购。由于 Stream 很大,我必须尽可能懒惰地执行此操作,即可以保留一天的 MyObject在内存中,但不能容纳更多的东西。

我怎样才能做到这一点?

2017-04-29 更新:

一个要求是我想在排序后继续在同一个流上工作!我想要这样的东西(伪代码):

Stream<MyObject> sortedStream = myStreamUnsorted().sort(onADailyBasis());

最佳答案

我建议采用以下解决方案:

将流的每个值存储在 TreeMap 中,以便立即对其进行排序。作为键使用对象的时间戳。

 Map<Date, MyObject> objectsOfTheDaySorted = new TreeMap<>();

我们需要知道最后必须从 map 中删除哪个对象。它只是一个对象,但存储它的成员必须(有效地)是最终的。所以我选择了一个简单的列表。

 List<MyObject> lastObject = new ArrayList<>();

将当前日期设置为整数。

 // just an example
 int currentDay = 23;

使用谓词来确定 currentDay 和任何路过对象的日期是否不匹配。

 Predicate<MyObject> predicate = myObject -> myObject.getTimestamp()
                    .toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate()
                    .getDayOfMonth() != currentDay;

现在流式传输您的流。使用 peek() 两次。首先要将对象放入 map 中。 其次覆盖列表中的对象。 使用 anyMatch() 作为终端操作并提交以前 创建谓词。一旦出现第一个匹配的对象 从第二天开始的标准,anyMatch() 终止流并返回 true。

 stream.peek(myObject -> objectsOfTheDaySorted.put(myObject.getTimestamp(), myObject))
       .peek(myObject -> lastObject.set(0, myObject))
       .anyMatch(predicate);

现在您只需删除已经属于第二天因此不属于您的 map 的最后经过的对象。

 objectsOfTheDaySorted.remove(lastObject.get(0).getTimestamp());

完成。您有一个已排序的对象 map ,它们都只属于一天。希望这符合您的期望。请在下面找到一个 block 中的完整代码,以便立即更好地复制它。

 Map<Date, MyObject> objectsOfTheDaySorted = new TreeMap<>();
 List<MyObject> lastObject = new ArrayList<>();

 // just an example
 int currentDay = 23;

 Predicate<MyObject> predicate = myObject -> myObject.getTimestamp()
                    .toInstant()
                    .atZone(ZoneId.systemDefault())
                    .toLocalDate()
                    .getDayOfMonth() != currentDay;

 stream.peek(myObject -> objectsOfTheDaySorted.put(myObject.getTimestamp(), myObject))
       .peek(myObject -> lastObject.set(0, myObject))
       .anyMatch(predicate);

 objectsOfTheDaySorted.remove(lastObject.get(0).getTimestamp());

关于java - 每天对 Java 8 Stream API 中的实体进行延迟排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43571256/

相关文章:

java-8 - 删除值以仅保留 N 次出现

java - JET Excelsior 创建 32 位 exe

java - 以编程方式调用 Java 类中的所有方法

java - Netbeans 中的 Lambda 表达式问题

java - 使用方法引用将 List 类型 <Integer> 转换为 String[] 数组

java - 为什么使用基类作为方法引用会导致编译器错误

java - 无法将 android.app.Fragment 转换为 mapping.SupportMapFragment

java - 想要借助正则表达式替换标签中的值属性吗?

generics - 显式调用 java 中的默认方法 - 当实现的接口(interface)使用泛型时

java - 展平从 Java 中的 json 字符串派生的 HashMap