使用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);