I am trying to generate a SortedMap using streams directly from two ArrayLists that come from a two different sources. My goal is to have the SortedMap store a Double attribute from the second list as key and the object from the first list as the value, if those objects have a matching attribute, which is checked by a helper Object.
So far, I can get it accomplished using:
SortedMap<Double, FirstObject> myMap = new TreeMap<>(Double::compareTo);
List<FirstObject> myList = firstDao.get(someId).stream()
.filter(firstobject -> secondDao.get(firstObject.getObjectId())
.stream()
.anyMatch(secondObject -> {
if (Helper.check(secondObject).matches()) {
myMap.put(
secondObject.getEfficiency(), firstObject
);
}
return Helper.check(secondObject).matches();
}))
.collect(Collectors.toList());
I have no use for myList that I am generating with that code, but so far it's the only way I have been able to populate the Map.
Is there a way I can populate directly to the SortedMap without having to generate that list?
Instead of creating a
filterthat causes side-effects you need to usecollect.One of the ways to do that is to create an intermediate Map which would associate each object returned by
firstDaowith the matching pair returned bysecondDao.Then create a stream over the entries of the intermediate map. Filter out the entry with an empty key (with no matching pair). And then apply
collect(Collectors.toMap()).Another slightly more concise way of addressing this problem would be to create a custom collector by utilizing
Collector.of()(the overall logic remains the same):Sidenote: when you need a
TreeMapit's better to useNavigableMapas an abstract type. This interface extendsSortedMapand offers a wide range of methods which are not accessible withSortedMap.Addressing the comment posted by OP
This code provided in the question creates a stream of objects retrieved by the means of the
firstDaoand the followingfilterwill update the mapmyMapif the predicate is meat by adding a new entry (or replacing the value of the existing one) withefficiencyof the very first encountered matching object from the stream created usingsecondDao.get()as a source.anyMatch- is a short-circuit operation and in case if there are the sameidbut differentefficiency, they will be ignored.This snippet from the solution above behaves in exactly the same way:
findFirstwill pick the very first object for whichsomeConditionwill be evaluated totrue(the case with an empty optional is being treated separately afterwards, andequals/hashCodeof the optional is delegates toequals/hashCodeimplementation of its value, so there's no room for discrepancies in the result).And I assume it's the expected behavior because there is no mention that code provided in the question is malfunctioning in some ways, as well as there's no sample data (which might lead to the opposite conclusion).
Hence, the claim that the above solution doesn't produce the expected result contradicts the current state of the question, since it's based on the logic of the original code.
Until the desired result isn't specified (by providing a sample data, or describing what's wrong with the original code) I see no possibility to improve the answer.