如何在Java中比较两个JSONArray?

时间:2019-07-17 06:17:23

标签: java json

如何比较两个JSONArray,如果这两个值匹配,则该函数必须返回true。例如:

array1=={1,2,3,4,5,6} 
array2=={9,10,11,1,12}

比较这两个数组时,结果为true,因为两个数组之间至少有一个共同的元素。数组中的位置并不重要。

我正在尝试通过一种原始方式(在每个Array中循环并比较值)进行比较。

private boolean compareArrays(JSONArray deviation, JSONArray deviationIds) throws JSONException {
for (int i = 0; i < deviation.length(); i++) {
for (int j = 0; j < deviationIds.length(); j++)
if(deviation.getString(i).equals(deviationIds.getString(j)))
    return true;
}
return false;
}

此代码有效,但是我想知道是否有一种方法可以更专业地做到这一点。也许可以通过使用JAVA Stream API来实现。 如果您需要任何其他信息,请发表评论。 谢谢!

4 个答案:

答案 0 :(得分:0)

对于任何匹配返回true 的要求可以重新公式化为对于非空交叉点返回true 的要求。将JSONArray转换为Collection可以很容易地做到这一点,例如像这样

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));

    }
}

但是,与直接使用JSONArray API的初始版本相比,代码要多得多。与直接的JSONArray API版本相比,它还会产生更多的迭代,这可能是问题,也可能不是问题。但是,总的来说,我认为在 transport 类型(例如JSONArray)上实现域逻辑不是一种好习惯,并且总会始终转换为域模型。

还请注意,生产就绪型代码还会对参数进行null检查。

答案 1 :(得分:0)

如果要使用JAVA Stream API,则对象必须是可迭代的。 如@Michal所述,您可以将其更改为Collection。 从@Michal的答案中,我们可以简化它,就像:

public class JsonArrayIntersectTest {

    private boolean anyMatch(JSONArray first, JSONArray second) throws JSONException {
        Set<Object> firstAsSet = convertJSONArrayToSet(first);
        Set<Object> secondIdsAsSet = convertJSONArrayToSet(second);
        // use stream API anyMatch
        return firstAsSet.stream()
                .anyMatch(secondIdsAsSet::contains);
    }

    private 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));

    }
}

答案 2 :(得分:-1)

您可以使用XStream来处理JSON映射

http://x-stream.github.io/json-tutorial.html

或者根据您检索字符串的逻辑,您可以比较为

 JSONCompareResult result = JSONCompare.compareJSON(json1, json2, JSONCompareMode.STRICT);
 System.out.println(result.toString());

答案 3 :(得分:-1)

好吧,您可以将这些物品收集到一个集合中并进行比较。

  Set<JSONObject> set = Stream.concat(deviation.stream(), deviationIds.stream())
                         .collect(Collectors.toSet());
  if(set.size() < deviation.length() + deviationIds.length()) {
    return true;
  } else {
    return false;
  }
}