使用stream将自定义比较器收集到TreeSet中

在Java 8中工作,我有一个像这样定义的TreeSet

 private TreeSet<PositionReport> positionReports = new TreeSet<>(Comparator.comparingLong(PositionReport::getTimestamp)); 

PositionReport是一个相当简单的类,定义如下:

 public static final class PositionReport implements Cloneable { private final long timestamp; private final Position position; public static PositionReport create(long timestamp, Position position) { return new PositionReport(timestamp, position); } private PositionReport(long timestamp, Position position) { this.timestamp = timestamp; this.position = position; } public long getTimestamp() { return timestamp; } public Position getPosition() { return position; } } 

这工作正常。

现在我想从TreeSet positionReports中删除timestamp超过某个值的条目。 但我无法弄清楚正确的Java 8语法来expression这一点。

这个尝试实际上是编译的,但给了我一个带有未定义比较器的新TreeSet

 positionReports = positionReports .stream() .filter(p -> p.timestamp >= oldestKept) .collect(Collectors.toCollection(TreeSet::new)) 

我如何expression,我想收集到比较Comparator.comparingLong(PositionReport::getTimestamp)TreeSet

我会想到类似的东西

 positionReports = positionReports .stream() .filter(p -> p.timestamp >= oldestKept) .collect( Collectors.toCollection( TreeSet::TreeSet(Comparator.comparingLong(PositionReport::getTimestamp)) ) ); 

但是这不能编译/看起来是方法引用的有效语法。

 Comparator<PositionReport> byTimestamp = Comparator.comparingLong(PositionReport::getTimestamp); Supplier<TreeSet<PositionReport>> supplier = () -> new TreeSet<PositionReport>(byTimestamp); positionReports = positionReports.stream() .filter(p -> p.getTimeStamp() >= oldestKept) .collect(Collectors.toCollection(supplier)); 

你可以在最后转换成一个SortedSet(假如你不介意附加的副本)。

 positionReports = positionReports .stream() .filter(p -> p.getTimeStamp() >= oldestKept) .collect(Collectors.toSet()); return new TreeSet(positionReports); 

这很简单,只需使用下一个代码:

  positionReports = positionReports .stream() .filter(p -> p.timestamp >= oldestKept) .collect( Collectors.toCollection(()->new TreeSet<>(Comparator.comparingLong(PositionReport::getTimestamp) ))); 

Collection上有一个方法,而不必使用streams: default boolean removeIf(Predicate<? super E> filter) 。 见Javadoc 。

所以你的代码看起来像这样:

 positionReports.removeIf(p -> p.timestamp < oldestKept);