代码之家  ›  专栏  ›  技术社区  ›  Oleksandr Riznyk

Java8流优先过滤

  •  3
  • Oleksandr Riznyk  · 技术社区  · 6 年前

    我有这样的代码:

    for (SomeObject object : objects) {
        if (object.getSomething() == Something.SomethingHighPriority) {
            return object;
        }
    }
    
    for (SomeObject object : objects) {
        if (object.getSomething() == Something.SomethingLowPriority) {
            return object;
        }
    }
    

    通过某种条件获取集合中的第一个元素。而且,优先权也很重要。我需要首先寻找一个元素,如果它不存在,就寻找第二个元素。

    现在我用这种方式重写了它,但它看起来比以前更难看了。

    Optional<SomeObject> object = 
        objects.stream()
               .filter(object -> object.getSomething() == Something.SomethingHighPriority)
               .findFirst();
    
    if (object.isPresent()) {
        return object.get();
    }
    
    object = objects.stream()
                    .filter(object -> object.getSomething() == Something.SomethingLowPriority)
                    .findFirst();
    
    // No other use cases
    return object.orElse(null);
    

    有没有可能让它少一些陈词滥调?

    2 回复  |  直到 6 年前
        1
  •  7
  •   Eran    6 年前

    return objects.stream()
                  .filter(object -> object.getSomething() == Something.SomethingHighPriority)
                  .findFirst()
                  .orElseGet(() -> objects.stream()
                                          .filter(object -> object.getSomething() == Something.SomethingLowPriority)
                                          .findFirst()
                                          .orElse(null));
    

    另一种选择是对 Stream object.getSomething() O(NlogN) 效率较低。

        2
  •  2
  •   fps    6 年前

    我认为你的代码是可以的,迭代一个集合两次是一个不错的方法。

    Map :

    Map<Something.Priority, Something> map = objects.stream()
        .filter(o -> o.getSomething() == Something.SomethingHighPriority
                  || o.getSomething() == Something.SomethingLowPriority)
        .collect(Collectors.toMap(
                    SomeObject::getSomething,
                    Function.identity(),
                    (oldObject, newObject) -> oldObject));
    
    SomeObject highPriority = map.get(Something.SomethingHighPriority);
    
    return highPriority == null ? map.get(Something.SomethingLowPriority) : highPriority;
    
        3
  •  0
  •   Bogdan    5 年前

    不知道什么东西对你来说是高优先级的,但你可以试试比较器。首先为high和low创建两个谓词。使用or运算符将它们添加到过滤器中,因为您需要两者进行比较并获得最大值。

        Predicate<SomeObject> somethingHighPriority= e -> e.getSomething() == Something.SomethingHighPriority;
        Predicate<SomeObject> somethingLowPriority= e -> e.getSomething() == Something.SomethingLowPriority;
        Optional<SomeObject> first = objects.stream()
                .filter(somethingHighPriority.or(somethingLowPriority)) 
                .max(Comparator.comparing(objects::getSomething()));
    
        if (first.isPresent()) {
            return first.get();
        }
        return null;