Reputation: 17
I have two lists and I have to create a map from them. One, I am iterating in for loop and second I wanted to go threw by a stream and than collect to map, but I have no idea how to use Collectors.toMap in that specific case. Is it possible?
I already made a solution, but not using stream, however I am very curious is it possible to do it and if yes, how to do it?
public void findMatch(List<ObjectA> objectAList, List<ObjectB> objectBList) {
Map<ObjectB, ObjectA> objectBObjectAMap = new HashMap<>();
for (ObjectB objectB : objectBList) {
if (isNull(objectB.getHandoverTime())) {
objectBObjectAMap.putAll(
objectAList
.stream()
.filter(objectA -> {
ObjectC objectC = objectB.getObjectC();
return objectA.getNumber().equals(objectC.getNumber())
&& objectA.getQuality().equals(objectC.getQuality());
})
.collect(Collectors.toMap(???)));
}
}
}
Upvotes: 1
Views: 114
Reputation: 41
I tried to restore your problem and I create three simple clasess
public class ObjectA {
Long number;
String quality;
...
}
public class ObjectB {
Long number;
String quality;
Date handoverTime;
ObjectC objectC;
...
}
public class ObjectC {
Long number;
String quality;
...
}
and main function with I hope your processing.
ObjectA a1 = new ObjectA();
a1.setNumber(1L);
a1.setQuality("aaa1");
ObjectA a2 = new ObjectA();
a2.setNumber(2L);
a2.setQuality("aaa2");
List<ObjectA> aList = new ArrayList<>();
aList.add(a1);
aList.add(a2);
ObjectB b1 = new ObjectB();
b1.setNumber(3L);
b1.setQuality("bbb1");
//b1.setHandoverTime(new Date());
ObjectC c1 = new ObjectC();
c1.setNumber(1L);
c1.setQuality("aaa1");
b1.setObjectC(c1);
ObjectB b2 = new ObjectB();
b2.setNumber(4L);
b2.setQuality("bbb2");
//b2.setHandoverTime(new Date());
ObjectC c2 = new ObjectC();
c2.setNumber(2L);
c2.setQuality("aaa2");
b2.setObjectC(c2);
List<ObjectB> bList = new ArrayList<>();
bList.add(b1);
bList.add(b2);
Map<ObjectB, ObjectA> mapzz = findMatch(aList, bList);
System.out.println(mapzz);
and following method
public static Map<ObjectB, ObjectA> findMatch(List<ObjectA> objectAList, List<ObjectB> objectBList) {
List<ObjectA> checkPoint1 = new ArrayList<>();
Map<ObjectB, ObjectA> mapzz = new HashMap<>();
mapzz.putAll(
objectBList.stream()
.filter(objB -> isNull(objB.getHandoverTime()))
.collect(Collectors.toMap(Function.identity(),
objB -> objectAList
.stream()
.filter((a) -> a.getNumber().equals(objB.getObjectC().getNumber()) && a.getQuality().equals(objB.getObjectC().getQuality()))
.peek(checkPoint1::add)
.findAny().get()
))
);
return mapzz;
}
Result is as follow:
{ObjectB{number=3, quality=bbb1, handoverTime=null, objectC=ObjectC{number=1, quality=aaa1}}=ObjectA{number=1, quality=aaa1}, ObjectB{number=4, quality=bbb2, handoverTime=null, objectC=ObjectC{number=2, quality=aaa2}}=ObjectA{number=2, quality=aaa2}}
I hope that it helps.
Upvotes: 0
Reputation: 393771
You can try with flatMap
:
Map<ObjectB, ObjectA> objectBObjectAMap =
objectBList.stream()
.filter(b -> isNull(b.getHandoverTime()))
.flatMap(b -> objectAList.stream()
.filter(a -> {
ObjectC c = b.getObjectC();
return a.getNumber().equals(c.getNumber()) &&
a.getQuality().equals(c.getQuality());
})
.map(a -> new SimpleEntry<>(b,a)))
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
This is assuming each ObjectB
instance will not be associated with more than one ObjectA
instance.
Upvotes: 2