猿问

Java Streams。如何将多个对象的列表加入并合并为一个对象?

我有一个与 Java 中的 Streams 相关的要求。我需要遍历一个对象列表,其中每个对象都有一个 Integer 属性和一个 List 属性。


我需要的是,如果相同的对象具有相同的 ID,我需要连接列表。让我用一些简单的代码来说明这个例子:


这里只定义了 2 个简单的类:


public static class Wrapper {

  Integer id ;

  List<Element> list;


  public Wrapper(Integer id, List<Element> list) {

    this.id = id;

    this.list = list;

  } 

}


public static class Element {

  String content ;


   public Element(String content) {

       this.content = content;

   } 

 }

现在在 Main Java 方法中,为示例的 porpuse 创建相同的对象:


    List<Wrapper> list=new ArrayList();

    ArrayList<Element> listForWrapper1= new ArrayList();

    listForWrapper1.add(new Element("Content A"));

    listForWrapper1.add(new Element("Content B"));


    ArrayList<Element> listForWrapper2= new ArrayList();

    listForWrapper2.add(new Element("Content C"));

    listForWrapper2.add(new Element("Content D"));


    ArrayList<Element> listForWrapper3= new ArrayList();

    listForWrapper3.add(new Element("Content E"));

    listForWrapper3.add(new Element("Content F"));


     Wrapper wrapper1=new Wrapper(1,listForWrapper1);

     Wrapper wrapper2=new Wrapper(2,listForWrapper2);

     //Here this Wrapper has the same ID than wrapper2

     Wrapper wrapper3=new Wrapper(2,listForWrapper3);



     //Adding Elements to List

     list.add(wrapper1);

     list.add(wrapper2);

     list.add(wrapper3);

如您所见,我在列表中添加了 3 个包装器,但其中 2 个具有相同的 ID


我想要的是当包装器 ID 在数组中相同时,只需合并两个列表。所以在这个例子中,结果应该是:


包含 2 个元素的列表:


元素 1 :ID 为 1 的包装对象,其列表属性中有 2 个元素,元素内容 A 和元素内容 B


元素 2:ID 为 2 的包装对象,其列表属性中有 4 个元素,元素内容 C、元素内容 D、元素内容 E 和元素内容 F。


如何使用 Streams 实现此结果?我想不出任何优雅的解决方案!


提前致谢!


List<Wrapper> combinedList=list.stream().....


慕后森
浏览 521回答 3
3回答

守着一只汪

您可以BinaryOperator<U> mergeFunction在 Collectors.toMap 中使用。Collection<Wrapper> wrapperList = wrappers.stream()&nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toMap(Wrapper::getId, x -> x),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (oldVal, newVal) -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; oldVal.getElements().addAll(newVal.getElements());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return oldVal;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }))&nbsp; &nbsp; &nbsp; &nbsp; .values();在上面的代码中,我写mergeFunction了总是返回 oldVal(oldVal, newVal) -> oldVal但你可以改变你想要的方式。Lambda 函数x -> x也可以写成Function.identity().

HUWWW

您可以使用Collectors.toMap()合并功能添加地图的值。Map<Integer, Wrapper> collect =&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; list.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toMap(w -> w.id,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; w -> w,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (w1, w2) -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;w1.list.addAll(w2.list);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return w1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );在职的import java.util.ArrayList;import java.util.List;import java.util.Map;import java.util.stream.Collectors;public class Main {&nbsp; &nbsp; public static void main(String[] args) {&nbsp; &nbsp; &nbsp; &nbsp; List<Wrapper> list=new ArrayList();&nbsp; &nbsp; &nbsp; &nbsp; ArrayList<Element> listForWrapper1= new ArrayList();&nbsp; &nbsp; &nbsp; &nbsp; listForWrapper1.add(new Element("Content A"));&nbsp; &nbsp; &nbsp; &nbsp; listForWrapper1.add(new Element("Content B"));&nbsp; &nbsp; &nbsp; &nbsp; ArrayList<Element> listForWrapper2= new ArrayList();&nbsp; &nbsp; &nbsp; &nbsp; listForWrapper2.add(new Element("Content C"));&nbsp; &nbsp; &nbsp; &nbsp; listForWrapper2.add(new Element("Content D"));&nbsp; &nbsp; &nbsp; &nbsp; ArrayList<Element> listForWrapper3= new ArrayList();&nbsp; &nbsp; &nbsp; &nbsp; listForWrapper3.add(new Element("Content E"));&nbsp; &nbsp; &nbsp; &nbsp; listForWrapper3.add(new Element("Content F"));&nbsp; &nbsp; &nbsp; &nbsp; Wrapper wrapper1=new Wrapper(1,listForWrapper1);&nbsp; &nbsp; &nbsp; &nbsp; Wrapper wrapper2=new Wrapper(2,listForWrapper2);&nbsp; &nbsp; &nbsp; &nbsp; //Here this Wrapper has the same ID than wrapper2&nbsp; &nbsp; &nbsp; &nbsp; Wrapper wrapper3=new Wrapper(2,listForWrapper3);&nbsp; &nbsp; &nbsp; &nbsp; //Adding Elements to List&nbsp; &nbsp; &nbsp; &nbsp; list.add(wrapper1);&nbsp; &nbsp; &nbsp; &nbsp; list.add(wrapper2);&nbsp; &nbsp; &nbsp; &nbsp; list.add(wrapper3);Map<Integer, Wrapper> collect =&nbsp; &nbsp; &nbsp; &nbsp; list.stream()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .collect(Collectors.toMap(w -> w.id,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; w -> w,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; (w1, w2) -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;w1.list.addAll(w2.list);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return w1;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; })&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; System.out.println( collect.values() );&nbsp; &nbsp; }}&nbsp;class Wrapper {&nbsp; &nbsp; Integer id ;&nbsp; &nbsp; List<Element> list;&nbsp; &nbsp; public Wrapper(Integer id, List<Element> list) {&nbsp; &nbsp; &nbsp; &nbsp; this.id = id;&nbsp; &nbsp; &nbsp; &nbsp; this.list = list;&nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;@Override&nbsp; &nbsp; &nbsp;public String toString() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return id + ":" + list;&nbsp; &nbsp; &nbsp;}&nbsp;}&nbsp;class Element {&nbsp; &nbsp; String content ;&nbsp; &nbsp; public Element(String content) {&nbsp; &nbsp; &nbsp; &nbsp; this.content = content;&nbsp; &nbsp; }&nbsp; &nbsp; &nbsp;@Override&nbsp; &nbsp; &nbsp;public String toString() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return content;&nbsp; &nbsp; &nbsp;}&nbsp;}输出[1:[Content A, Content B], 2:[Content C, Content D, Content E, Content F]]

胡子哥哥

你可以试试这个:Map<Integer, Wrapper> map = list.stream().collect(Collectors.toMap(wrapper -> wrapper.id /*Use the ids as the keys*/, wrapper -> wrapper /*Return the same wrapper as the value*/, (w1, w2) -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;w1.list.addAll(w2.list); // If a wrapper with the same id is found, then merge the list of wrapper 2 to the list of wrapper 1 and return wrapper 1.&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return w1;&nbsp; &nbsp; &nbsp;}));list = new ArrayList<>(map.values()); // Create new ArrayList with the values of the map.System.out.println(list); // [cci.Test$Wrapper@4eec7777, cci.Test$Wrapper@3b07d329]
随时随地看视频慕课网APP

相关分类

Java
我要回答