Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.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_Arrays_List_Java Stream_Grouping - Fatal编程技术网

如何获取Java流中每种类型(按属性选择)的第一个对象(带有任何按函数排序的对象)

如何获取Java流中每种类型(按属性选择)的第一个对象(带有任何按函数排序的对象),java,arrays,list,java-stream,grouping,Java,Arrays,List,Java Stream,Grouping,想象一个具有3个属性的简单对象: public class Obj { boolean toBeAdded; String type; int order; public Obj(boolean toBeAdded, String type, int order) { this.toBeAdded = toBeAdded; this.type = type; this.order = order; }

想象一个具有3个属性的简单对象:

public class Obj {

    boolean toBeAdded;
    String type;
    int order;

    public Obj(boolean toBeAdded, String type, int order) {
        this.toBeAdded = toBeAdded;
        this.type = type;
        this.order = order;
    }

    public boolean isToBeAdded() {
        return toBeAdded;
    }

    public String getType() {
        return type;
    }

    public int getOrder() {
        return order;
    }

}
假设我有一个包含多个不同类型的
Obj
s的列表:

import java.util.Arrays;
import java.util.List;

public class Utils {

    static List<Obj> createA(){
        List<Obj> list = Arrays.asList(
                new Obj(true, "A", 1),
                new Obj(false, "A", 2),
                new Obj(true, "A", 3),
                new Obj(false, "A", 4)
        );
        return list;
    }


    static List<Obj> createB(){
        List<Obj> list = Arrays.asList(
                new Obj(true, "B", 1),
                new Obj(false, "B", 2),
                new Obj(true, "B", 3),
                new Obj(false, "B", 4)
        );
        return list;
    }


    static List<Obj> createC(){
        List<Obj> list = Arrays.asList(
                new Obj(false, "C", 1),
                new Obj(false, "C", 2),
                new Obj(true, "C", 3),
                new Obj(true, "C", 4)
        );
        return list;
    }
}

然而,这只是做简单的部分过滤和排序。对于每个
类型
,我仍然需要执行类似于
findFirst()
的操作。有没有办法做到这一点

我需要做3个不同的流(每种类型一个)然后合并列表吗?有没有一种方法可以做到这一点,而不知道我们将有多少种类型?
我还阅读了有关
collector(Collectors.groupingBy())
的内容,但这会为每种类型创建不同的映射,这是我不想要的。

使用
groupingBy
以及
minBy
/
maxBy
的下游功能在这里会有所帮助。这将提供一个映射来查找每个类型是否存在筛选后的值

Map<String, Optional<Obj>> groupMaxOrderByType = list.stream()
        .filter(Obj::isToBeAdded)
        .collect(Collectors.groupingBy(Obj::getType,
                Collectors.maxBy(Comparator.comparingInt(Obj::getOrder)))); //highest order
编辑:或者,如果要将所有此类当前类型收集到最终结果中,则可以按照以下步骤访问
映射的值

List<Obj> result = groupMaxOrderByType.values().stream()
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());

这确实是朝着好的方向发展。这将创建一个包含3个条目的映射,每个条目只有一个条目,正如我最初询问的那样,这是最高的
order
值。但是有没有一种方法可以立即将其简化为列表?@pmendesm您可以访问
映射的
值。(
stream
ing和
filter
ing根据您的进一步要求)我可以这样做:
List newList=newarraylist();groupMaxOrderByType.forEach((s,obj)->newList.add(obj.get())我想知道这是否可以用更少的操作来实现。排序为:
List filteredList=List.stream().filter(Obj::isToBeAdded)、substream(Obj::getType)、sorted(Comparator.comparingit(Obj::getOrder).reversed()).findFirst().collect(collector.toList())被接受为答案在替换
收集器.groupingBy(Obj::getType,Collectors.maxBy(Comparator.comparingit(Obj::getOrder))
时,您不需要处理
可选的
收集器.toMap(Obj::getType,Function.identity(),binarymoperator.maxBy(Comparator.comparingit(Obj::getOrder)))
Obj maxPerTypeA = groupMaxOrderByType.get("A").orElse.. // similar for each type
List<Obj> result = groupMaxOrderByType.values().stream()
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());
Map<String, Obj> groupMaxOrderByType = list.stream()
        .filter(Obj::isToBeAdded)
        .collect(Collectors.toMap(Obj::getType, Function.identity(), 
                BinaryOperator.maxBy(Comparator.comparingInt(Obj::getOrder))));
List<Obj> result = new ArrayList<>(groupMaxOrderByType.values());