I have some data:
List<String> constData = new ArrayList<>();
constData.add("data10115");
constData.add("data8134");
constData.add("data8933");
constData.add("data8206");
String strJSON = "[{\"type1\":\"data8933,data10115\",\"type2\":\"data8134,data8135,data9931\"},{\"type1\":\"data8204,data10115\",\"type2\":\"data8773,data8206,data9931\"}]";
Gson gson = new GsonBuilder().create();
List<Map<String, String>> mappedJSON = gson.fromJson(strJSON, new TypeToken<List<Map<String, String>>>(){}.getType());
Now I need to check if constData have some intersections with mappedJSON with some rules:
System.out.println(
mappedJSON.stream()
.anyMatch(f -> f.entrySet().stream()
.allMatch(
e -> constData.stream()
.anyMatch(CollectionUtils.emptyIfNull(new ArrayList<>(Arrays.asList(e.getValue().split(","))))::contains)
))
);
Now I want not just to check the condition, but also have the array of the interceptions. Is there any way to process this (check condition and retrieve intersections) with single pass?
I only have such variant:
Set<String> result1 = new HashSet<>();
for(Map<String, String> mapdata : mappedJSON) {
Map<String, List<String>> mapNode = new HashedMap<>();
for (Map.Entry<String, String> entry : mapdata.entrySet()) {
List<String> listNode = new ArrayList<>();
constData.stream()
.filter(CollectionUtils.emptyIfNull(new ArrayList<>(Arrays.asList(entry.getValue().split(","))))::contains)
.collect(Collectors.toList()).forEach(l -> listNode.add(l));
if(listNode.size() > 0) {
mapNode.putIfAbsent(entry.getKey(), listNode);
}
}
if(mapNode.entrySet().size() == mapdata.entrySet().size()) {
result1.addAll(mapNode.entrySet().stream().map(x -> x.getValue()).flatMap(List::stream).collect(Collectors.toList()));
}
}
System.out.println(result1);
This code works as I need - I can check condition (set will be empty if condition is false) and get data with the single pass. But it's look "heavy")
Or I can use lambdas to check and after that to get data:
if(
mappedJSON.stream()
.anyMatch(f -> f.entrySet().stream()
.allMatch(
e -> constData.stream()
.anyMatch(CollectionUtils.emptyIfNull(new ArrayList<>(Arrays.asList(e.getValue().split(","))))::contains)
))
) {
List<String> result0 = new ArrayList<>();
mappedJSON.stream()
.forEach(
m -> m.entrySet().stream()
.forEach(
s -> constData.stream()
.filter(CollectionUtils.emptyIfNull(new ArrayList<>(Arrays.asList(s.getValue().split(","))))::contains)
.collect(Collectors.toList()).forEach(l -> result0.add(l))
)
);
System.out.println(result0);
}
This is also works, but here I need two passes.
Is there any other "light and beautiful" way?
More shorter version of my question: Main logic expression is here:
mappedJSON.stream().anyMatch(f -> f.entrySet().stream().allMatch(e -> constData.stream().anyMatch(Arrays.asList(s.getValue().split(","))::contains)))
Is there any "easy" way to get intersections from inner part of this expression (I mean this part: anyMatch(Arrays.asList(s.getValue().split(","))::contains)) ?