迭代Java中的查询结果列表,并根据键值创建对象

Iterate a list of query results in Java and create objects based on a key value

我执行了查询并得到了这个对象的结果列表:

public MyObject {
      private String key;
      private String value1;
      private Integer value2;
}

结果如下所示:

键 值 1 值 2
1 WWW EEE
1 WWW AAA
2 WW​​W EEE

我想迭代此列表并创建一个类似这样的列表,并按键对其进行分组。

//first object of the list
public MyCreatedObject {
      private String key; //1
      private List<Value1> value1List; //WWW, WWW
      private List<Value2> value2List; //EEE, AAA
}

//second object of the list
public MyCreatedObject {
      private String key; //2
      private List<Value1> value1List; //WWW
      private List<Value2> value2List; //EEE
}

我尝试过使用流、迭代和一些东西,但我真的很难解决这个问题。

有人可以帮我吗?

非常感谢大家

您可以通过添加两种方法将 MyCreatedObject 用作收集器:

static Collector<MyObject, ?, MyCreatedObject> collector() {
    return Collector.of(MyCreatedObject::new, MyCreatedObject::add, MyCreatedObject::merge);
}

void add(MyObject o) {
    key = o.key;
    value1List.add(o.value1);
    value2List.add(o.value2);
}

MyCreatedObject merge(MyCreatedObject other) {
    key = other.key;
    value1List.addAll(other.value1List);
    value2List.addAll(other.value2List);
    return this;
}

然后将其用作 groupingBy() 的下游收集器:

Map<String, MyCreatedObject> grouped = list.stream()
        .collect(Collectors.groupingBy(o -> o.key, MyCreatedObject.collector()));

Ideone Demo

或者,您可以使用 toMap():

add() 转换为构造函数和组
Map<String, MyCreatedObject> grouped = list.stream()
        .collect(Collectors.toMap(o -> o.key, MyCreatedObject::new, MyCreatedObject::merge));

Ideone Demo 2

试试这个。

record MyObject(String key, String value1, String value2) {}
record MyCreatedObject(String key, List<String> value1List, List<String> value2List) {}

public static void main(String[] args) {

    List<MyObject> list = List.of(
        new MyObject("1", "WWW", "EEE"),
        new MyObject("1", "WWW", "AAA"),
        new MyObject("2", "WWW", "EEE"));

    Map<String, MyCreatedObject> map = new LinkedHashMap<>();
    for (MyObject obj : list) {
        MyCreatedObject c = map.computeIfAbsent(obj.key(),
            k -> new MyCreatedObject(k, new ArrayList<>(), new ArrayList<>()));
        c.value1List().add(obj.value1());
        c.value2List().add(obj.value2());
    }
    List<MyCreatedObject> result = new ArrayList<>(map.values());

    for (MyCreatedObject obj : result)
        System.out.println(obj);
}

输出:

MyCreatedObject[key=1, value1List=[WWW, WWW], value2List=[EEE, AAA]]
MyCreatedObject[key=2, value1List=[WWW], value2List=[EEE]]

Collectors.toMap 与合并函数可用于构建映射 Map<String, MyCreatedObject> 然后将其值转换为列表,前提是提供了 MyCreatedObject 的适当的全参数构造函数:

List<MyObject> input = ... ; // setup input data
List<MyCreatedObject> result = new ArrayList<>(input
    .stream()
    .collect(Collectors.toMap(
        MyObject::getKey, // 
        mo -> new MyCreatedObject(
            mo.getKey(), 
            new ArrayList<>(Arrays.asList(mo.getValue1())), 
            new ArrayList<>(Arrays.asList(mo.getValue2()))
        ),
        (co1, co2) -> { // merge inner lists in MyCreatedObject
            co1.getValue1List().addAll(co2.getValue1List());
            co1.getValue2List().addAll(co2.getValue2List());
            return co1;
        }
        //, LinkedHashMap::new // optional supplier to keep insertion order
    ))
    .values()
);