2

Update:
Using your suggestions in checking between strings, I found out that the difference is on the arrangement of some fields since these strings are actually JSON strings.

Example:
the field username: johndoe@dummy.com on string1 is located at the beginning, but is located somewhere in the middle in string2. I wonder if there is a way to check or compare 2 json objects regardless of the arrangement of their fields/properties... as long as their contents (field values) are the same.

What I tried:

private boolean sameJsonObject(Object o1, Object o2) throws IOException {
    if (o1 == null || o2 == null) {
        return false;
    }

    JsonNode json1 = mapper.readTree(mapper.writeValueAsString(o1));
    JsonNode json2 = mapper.readTree(mapper.writeValueAsString(o2));

    return json1.equals(json2);
}

this works but I am sure that this can be improved.

Original Problem:
I would like to check if two strings are equal, but these strings are really long that it cannot be set to a variable/string object and would get string constant too long.

I know that there is equals(), equalsIgnoreCase(), and StringUtils.equals(s1, s2) but none of these seems to work.

The strings that I am comparing came from two different sources and comparing it manually get the same results (I mean the contents are the same).

I tried to post the sample strings here but I can't. The size of each string to compare is more than 30k (170k each string).

btw, these strings are actual data (json) and they are really huge and I want to test its equality (content).

Is there a way to do the checking in java?

Thanks!

Borgy Manotoy
  • 1,960
  • 5
  • 27
  • 42
  • you may want to consider to [sanitize](https://happycoding.io/tutorials/java-server/sanitizing-user-input) your strings before comparing – fantaghirocco Mar 08 '19 at 14:42
  • `String.equals` works regarding of length so if you have `s1.equals(s2) == false` then the strings are not equal and that is that. Since you are comparing JSON, it is possible that that inequality is due to whitespace , line breaks or even the ordering of the elements. – David Soroko Mar 08 '19 at 14:57
  • Is it possible to accept multiple answers? Yours is correct for checking long string and getting the index where it did not match. But for checking json strings... @davidxxx answer works – Borgy Manotoy Mar 12 '19 at 10:52
  • Since the mail question is checking long string, I accept your answer. Thanks :) – Borgy Manotoy Mar 12 '19 at 10:53
  • You are welcome. And as upvoted the other answers, too... Everybody got his share here. – GhostCat Mar 12 '19 at 10:54

3 Answers3

3

The simple answer is: compare the two strings char by char.

In other words: most likely, the built-in Java string compare methods are correct, leading to: your input strings aren't equal. It is extremely unlikely that equal strings result in equals() giving false.

Thus the reasonable first option is: change your comparison code so that it:

  • iterates the first string, char by char
  • fetches the corresponding char from the second string
  • compares those (either "full" equals, or ignoring case)
  • on mismatch: print out the index and the two different chars (where you ensure to print something like "<" + thatChar + ">" just to ensure that non-printable chars, or maybe using Character.getNumericValue())

So, the answer here is basically to enable yourself to do proper debugging.

GhostCat
  • 137,827
  • 25
  • 176
  • 248
3

btw, these strings are actual data (json) and they are really huge and I want to test its equality (content).

If these are JSON data, don't compare them with String.
Use a JSON library (Jackson, GSON or anything)to represent these data and also to compare them (equals() is generally overridden).It will compare them more cleanly and more specifically by considering or ignoring things like whitespace, node order and so forth... You can find some examples here.

You could consider more particularly SkyScreamer library that provides multiple flavors to compare JSON. For example this JSONAssert.assertEquals() overload :

public static void assertEquals(org.json.JSONArray expected,
                                org.json.JSONArray actual,
                                JSONCompareMode compareMode)
                         throws org.json.JSONException

where you can specify a JSONCompareMode object such as JSONCompareMode.LENIENT.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • is using jackson, can compare json objects regardless of the arrangement of the fields/properties? I found out that the difference between strings are the arrangement of some fields. I mean field1 on string1 is location on the beginning of string1... but field1 is located on the middle of string2. Is there a way in jackson to compare json contents? – Borgy Manotoy Mar 08 '19 at 15:01
  • In fact for Jackson it depends on the type of Node compared. Each one may override `equals()` . For your requirement, you should master this part. So `SkyScreamer` is probably better. – davidxxx Mar 08 '19 at 15:14
2

170k is not too large for a String, though it is large for a string literal in source code.

Load your two strings from files that contain them, and compare in the normal way using equals.

You mention that the strings are not text but JSON. For most purposes, you'd want to normalize your json (make the whitespace, property order and punctuation the same).

Pete Kirkham
  • 48,893
  • 5
  • 92
  • 171