我对Java中的流有一个要求。 我需要遍历对象列表,其中每个对象都具有Integer属性和List属性。
我需要的是,如果相同的对象具有相同的ID,则需要合并列表。 让我用一些简单的代码来说明示例:
这里只定义了两个简单的类:
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方法中,为示例的用法创建相同的对象:
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的包装对象,其list属性中包含2个元素,即元素内容A和元素内容B
元素2 :ID为2的包装对象,其list属性中包含4个元素,即元素内容C,元素内容D,元素内容E和元素内容F。
如何使用Streams获得此结果?我想不到任何优雅的解决方案!
谢谢!
List<Wrapper> combinedList=list.stream().....
答案 0 :(得分:2)
您可以在Collectors.toMap`中使用BinaryOperator<U> mergeFunction
。
Collection<Wrapper> wrapperList = wrappers.stream()
.collect(Collectors.toMap(Wrapper::getId, x -> x),
(oldVal, newVal) -> {
oldVal.getElements().addAll(newVal.getElements());
return oldVal;
}))
.values();
在上面的代码中,我编写了mergeFunction
以始终返回oldVal (oldVal, newVal) -> oldVal
,但是您可以更改所需的方式。 Lambda函数x -> x
也可以写为Function.identity()
。
答案 1 :(得分:1)
您可以使用Collectors.toMap()
通过合并功能添加地图的值。
Map<Integer, Wrapper> collect =
list.stream()
.collect(Collectors.toMap(w -> w.id,
w -> w,
(w1, w2) -> {
w1.list.addAll(w2.list);
return w1;
})
);
工作
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
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);
Map<Integer, Wrapper> collect =
list.stream()
.collect(Collectors.toMap(w -> w.id,
w -> w,
(w1, w2) -> {
w1.list.addAll(w2.list);
return w1;
})
);
System.out.println( collect.values() );
}
}
class Wrapper {
Integer id ;
List<Element> list;
public Wrapper(Integer id, List<Element> list) {
this.id = id;
this.list = list;
}
@Override
public String toString() {
return id + ":" + list;
}
}
class Element {
String content ;
public Element(String content) {
this.content = content;
}
@Override
public String toString() {
return content;
}
}
输出
[1:[Content A, Content B], 2:[Content C, Content D, Content E, Content F]]
答案 2 :(得分:0)
您可以尝试以下方法:
TO_DATE(TRIM(:DR430_LAST_MOD_DATE), 'YYYYMMDD')