Java Stream:过滤多个范围

Yad*_*ore 8 java lambda java-8 java-stream

我正在尝试过滤资源并根据字段排除一些元素。要排除,我有一个集合(包含需要排除的 id)和一个列表(它包含需要排除的多个 id 范围)。我写了下面的逻辑,我对第二个过滤器逻辑不满意。我们有没有更好的方法可以用 Java 8 做到这一点?我也需要为包括范围做同样的事情。

Set<String> extensionsToExclude = new HashSet<>(Arrays.asList("20","25","60","900"));
List<String> rangesToExclude = new ArrayList<>(Arrays.asList("1-10","20-25","50-70","1000-1000000"));
return directoryRecords.stream()
        .filter((directoryRecord) -> !extensionsToExclude.contains(directoryRecord.getExtensionNumber()))
        .filter((directoryRecord -> {
            Boolean include = true;
            for(String s : rangesToExclude) {
                String [] rangeArray = s.split("-");
                Integer extension = Integer.parseInt(directoryRecord.getExtensionNumber());
                if(extension <= Integer.parseInt(rangeArray[0]) && extension >= Integer.parseInt(rangeArray[1])) {
                    include = false;
                }
            }
            return include;
        }))
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

谢谢 :)

ern*_*t_k 8

我会用一个自定义Range类来做,比如:

class Range {
    private long start;
    private long end;

    Range(String start, String end) {
        this.start = Long.parseLong(start);
        this.end = Long.parseLong(end);
    }

    Range(String range) {
        this(range.split("-")[0], range.split("-")[1]);
    }

    boolean inRange(long n) {
        returns start <= n && n <= end;
    }
}
Run Code Online (Sandbox Code Playgroud)

这将使这样的事情成为可能:

List<Range> ranges = rangesToExclude.stream()
                     .map(Range::new).collect(Collectors.toList());
return directoryRecords.stream()
        .filter((directoryRecord) -> !extensionsToExclude
                                    .contains(directoryRecord.getExtensionNumber()))
        .filter(directoryRecord -> ranges.stream()
                                    .noneMatch(r -> r.isInRange(directoryRecord)))
        .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

我个人认为你的第一个过滤器足够好,可以按原样保存。

  • 当我们谈论“rangesToExclude”时,不应该是“noneMatch”吗?我想,使用 `TreeSet&lt;Range&gt;` 可能有一个更优雅的解决方案...... (2认同)