如何透過 Set 來比較2個 JSONArray 裡的內容:
https://stackoverflow.com/questions/57069595/how-do-i-compare-two-jsonarray-in-java
The requirement for any match return true can be re-formulated as for non-empty intersection return true. Converting the JSONArray
into Collection
allows for that quite easily, e.g. like this
public class JsonArrayIntersectTest {
private boolean anyMatch(JSONArray first, JSONArray second) throws JSONException {
Set<Object> firstAsSet = convertJSONArrayToSet(first);
Set<Object> secondIdsAsSet = convertJSONArrayToSet(second);
//Set<Object> intersection = Sets.intersection(firstAsSet, secondIdsAsSet); // use this if you have Guava
Set<Object> intersection = firstAsSet.stream()
.distinct()
.filter(secondIdsAsSet::contains)
.collect(Collectors.toSet());
return !intersection.isEmpty();
}
Set<Object> convertJSONArrayToSet(JSONArray input) throws JSONException {
Set<Object> retVal = new HashSet<>();
for (int i = 0; i < input.length(); i++) {
retVal.add(input.get(i));
}
return retVal;
}
@Test
public void testCompareArrays() throws JSONException {
JSONArray deviation = new JSONArray(ImmutableSet.of("1", "2", "3"));
JSONArray deviationIds = new JSONArray(ImmutableSet.of("3", "4", "5"));
Assert.assertTrue(anyMatch(deviation, deviationIds));
deviation = new JSONArray(ImmutableSet.of("1", "2", "3"));
deviationIds = new JSONArray(ImmutableSet.of("4", "5", "6"));
Assert.assertFalse(anyMatch(deviation, deviationIds));
}
}
However, that is much more code then the initial version using the JSONArray
API directly. It also produces much more iteration then the direct JSONArray
API version, which might or might not be a problem. In general, I would however argue that it is not a good practise to implement domain logic on transport types such as JSONArray
and would always convert into a domain model anyway.
Please also note that production-ready code would additionally do null
checks on arguments.