Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用优先级通过集合和筛选器进行流式处理_Java_Java 8_Java Stream - Fatal编程技术网

Java 使用优先级通过集合和筛选器进行流式处理

Java 使用优先级通过集合和筛选器进行流式处理,java,java-8,java-stream,Java,Java 8,Java Stream,我正在尝试根据某个优先级筛选集合。 集合由具有特定类型字段的实体组成 因此,我想做以下几点: 对集合进行迭代/流式处理,并 查找具有getType=“type1”的第一个实体。如果此实体的价格大于0,则返回此实体。否则 查找具有getType=“type2”的下一个实体。如果价格>0,则返回该价格。否则 查找具有getType=“type3”的下一个实体。如果价格>0,则返回该价格 查找具有getType=“type4”的下一个实体。如果价格>0,则返回该价格 查找具有getType=“

我正在尝试根据某个优先级筛选集合。 集合由具有特定类型字段的实体组成

因此,我想做以下几点: 对集合进行迭代/流式处理,并

  • 查找具有getType=“type1”的第一个实体。如果此实体的价格大于0,则返回此实体。否则

  • 查找具有getType=“type2”的下一个实体。如果价格>0,则返回该价格。否则

  • 查找具有getType=“type3”的下一个实体。如果价格>0,则返回该价格

  • 查找具有getType=“type4”的下一个实体。如果价格>0,则返回该价格

  • 查找具有getType=“type5”的下一个实体。如果价格>0,则返回该价格

  • 否则返回


  • 我正在尝试使用流进行此操作,但在筛选步骤中,我无法创建此优先级类型的筛选。我还尝试使用for循环遍历集合,但是不确定如何实现type1的
    findFirst
    实体,然后是type2等等。如果您稍微重新表述一下需求,它使流的一系列操作的转换更加清晰-您应该返回具有最小
    类型的
    price>0
    的第一个项目:

    MyEntity result = myList.stream()
                            .filter(e -> e.getPrice() > 0)
                            .min(Compartor.comparing(MyEntity::getType))
                            .orElse(null);
    

    如果您稍微重新表述一下需求,它会使对流的一系列操作的转换更加清晰-您应该返回具有最小
    类型的
    price>0
    的第一个项目:

    MyEntity result = myList.stream()
                            .filter(e -> e.getPrice() > 0)
                            .min(Compartor.comparing(MyEntity::getType))
                            .orElse(null);
    

    原始-无效的缩减方法

    一个选项是翻转操作顺序。例如:在“price>0”处进行筛选,然后在遇到元素时减少流。例:

    stream.filter(elem -> elem.price > 0)
        .reduce((elem1, elem2) -> elem1.type.compareTo(elem2.type) < 0 ? elem1 : elem2)
    
    stream.filter(elem->elem.price>0)
    .reduce((elem1,elem2)->elem1.type.compareTo(elem2.type)<0?elem1:elem2)
    
    编辑-更正确的缩减方法

    通常,最好使流操作保持无状态。因此,创建一个处理遍历列表并返回结果的函数可能是更正确的方法。使用streams,可以定义一个自定义的“reducer”,它跟踪先前检查的类型,以确定下一个结果是否可能是有效匹配。一旦找到有效的匹配项,就会始终返回该匹配项

        public static void main(String[] args)
        {
            List<Entity> data = Arrays.asList(eee(2, 6), eee(1, 0), eee(1, 10), eee(3, 7), eee(2, 0), eee(3, 5), eee(4, 0), eee(5, 0));
            System.out.println(data.stream().reduce(new Reducer()).filter(entity -> entity != Reducer.NO_MATCH));
        }
    
        /*Once a match is found, always use it. For a given type, only the first found entity of that type will be used*/
        public static final class Reducer implements BinaryOperator<Entity>
        {
            private int priorValidType;
            Reducer(){ this.priorValidType = 0; }
    
            @Override
            public Entity apply(Entity result, Entity newElem)
            {
                int nextValidType = priorValidType + 1;
                if(priorValidType > 0 && result != NO_MATCH) return result; /*Match already found, use it*/
                if(result.type == nextValidType && result.price > 0) { priorValidType = nextValidType; return result; } /*result is a match*/
                if(newElem.type == nextValidType && newElem.price > 0) { priorValidType = nextValidType; return newElem; } /*newElem is a match*/
                if(result.type == nextValidType || newElem.type == nextValidType) { priorValidType = nextValidType; }
                return NO_MATCH; /*No match has been found*/
            }
    
            public static final Entity NO_MATCH = new Entity(-1, -1);
        }
    
        public static final class Entity
        {
            private final int price, type;
            Entity(int type, int price){ this.price = price; this.type = type; }
            public String toString(){ return "(" + type + ", " + price + ")"; }
            int getPrice(){ return price; }
            int getType(){ return type; }
            public static Entity eee(int type, int price){ return new Entity(type, price); }
        }
    
    publicstaticvoidmain(字符串[]args)
    {
    列表数据=数组.asList(eee(2,6),eee(1,0),eee(1,10),eee(3,7),eee(2,0),eee(3,5),eee(4,0),eee(5,0));
    System.out.println(data.stream().reduce(new Reducer()).filter(entity->entity!=Reducer.NO_MATCH));
    }
    /*一旦找到匹配项,请始终使用它。对于给定类型,将仅使用该类型的第一个找到的实体*/
    公共静态最终类缩减器实现BinaryOperator
    {
    私有int-priorValidType;
    Reducer(){this.priorValidType=0;}
    @凌驾
    公共实体应用(实体结果、实体新元素)
    {
    int nextValidType=priorValidType+1;
    如果(priorValidType>0&&result!=无匹配项)返回结果;/*已找到匹配项,请使用它*/
    如果(result.type==nextValidType&&result.price>0){priorValidType=nextValidType;return result;}/*结果匹配*/
    如果(newElem.type==nextValidType&&newElem.price>0){priorValidType=nextValidType;return newElem;}/*newElem是匹配项*/
    如果(result.type==nextValidType | | newElem.type==nextValidType){priorValidType=nextValidType;}
    return NO_MATCH;/*未找到匹配项*/
    }
    公共静态最终实体不匹配=新实体(-1,-1);
    }
    公共静态最终类实体
    {
    私人最终整数价格,类型;
    实体(int-type,int-price){this.price=price;this.type=type;}
    公共字符串toString(){return“(“+type+”,“+price+”);}
    int getPrice(){返回价格;}
    int getType(){return type;}
    公共静态实体eee(int类型,int价格){返回新实体(类型,价格);}
    }
    
    编辑-使用过滤器的替代方法

    可以创建一个过滤器,它执行类似于reduce方法的操作,并且在调用“findFirst”时具有短路的好处。在下面的示例中,第一个过滤器仅允许与给定类型(顺序)的第一次相遇通过。第二个过滤器确认它是有效的

        public static void main(String[] args)
        {
            List<Entity> data = Arrays.asList(eee(2, 6), eee(1, 0), eee(1, 10), eee(3, 7), eee(2, 0), eee(3, 5), eee(4, 0), eee(5, 0));
            System.out.println(data.stream().filter(new FirstTypeMatch()).filter(entity -> entity.price > 0).findFirst());
        }
    
        /*Filter where the element is the first of the given type*/
        public static final class FirstTypeMatch implements Predicate<Entity>
        {
            private int priorValidType = 0;
            @Override
            public boolean test(Entity nextElem)
            {
                if(nextElem.type == (priorValidType + 1)){ priorValidType++; return true; }
                return false;
            }
        }
    
    publicstaticvoidmain(字符串[]args)
    {
    列表数据=数组.asList(eee(2,6),eee(1,0),eee(1,10),eee(3,7),eee(2,0),eee(3,5),eee(4,0),eee(5,0));
    System.out.println(data.stream().filter(new FirstTypeMatch()).filter(entity->entity.price>0.findFirst());
    }
    /*元素是给定类型的第一个的过滤器*/
    公共静态final类FirstTypeMatch实现谓词
    {
    private int priorValidType=0;
    @凌驾
    公共布尔测试(实体nextem)
    {
    if(nextElem.type==(priorValidType+1)){priorValidType++;返回true;}
    返回false;
    }
    }
    
    原始-无效还原方法

    一个选项是翻转操作顺序。例如:在“price>0”处进行筛选,然后在遇到元素时减少流。例:

    stream.filter(elem -> elem.price > 0)
        .reduce((elem1, elem2) -> elem1.type.compareTo(elem2.type) < 0 ? elem1 : elem2)
    
    stream.filter(elem->elem.price>0)
    .reduce((elem1,elem2)->elem1.type.compareTo(elem2.type)<0?elem1:elem2)
    
    编辑-更正确的缩减方法

    通常,最好使流操作保持无状态。因此,创建一个处理遍历列表并返回结果的函数可能是更正确的方法。使用streams,可以定义一个自定义的“reducer”,它跟踪先前检查的类型,以确定下一个结果是否可能有效
    MyClass selected = Arrays.stream(types)
            .map(type -> list.stream()
                    .filter(obj -> obj.getType().equals(type))
                    .findFirst()
                    .orElse(null))
            .filter(a -> a != null && a.getPrice() > 0)
            .findFirst().orElse(new MyClass(-1, "Empty"));
    
    System.out.println(selected);
    
    [10, Type2]
    
    
    Optional<Entity> entity = list.stream().sorted(Comparator.comparing(Entity::getType))
    .filter( e -> e.price > 0 ).findFirst();
         
    
    if(entity.isPresent()){
        System.out.println(entity.get().getType()); // test to verify 
    }