Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: Compare Strings with keywords in different order

I have two Strings that look like this:

String str1 = "[0.7419,0.7710,0.2487]";
String str2 = "[\"0.7710\",\"0.7419\",\"0.2487\"]";

and I want to compare them and be equal despite the order difference...

Which is the fastest and simplest way to do that?

Should I split each one into Arrays and compare the two Arrays? Or not? I guess I have to remove the "[","]",""" characters to make it clearer so I did. And I also replaced the "," with " " but I don't know if this helps...

Thanks in advance :)

Edit: My Strings will not always be a set of doubles or floats. They may also be actual words or a set of characters.

like image 870
T. Kofidis Avatar asked Jul 12 '26 13:07

T. Kofidis


1 Answers

Because you have a mixed result type, you need to first handle it as a mixed input

Here's how I would replace it, particularly for longer strings.

private Stream<String> parseStream(String in) {
    //we'll skip regex for now and can simply hard-fail bad input later
    //you can also do some sanity checks outside this method
    return Arrays.stream(in.substring(1, in.length() - 1).split(",")) //remove braces
        .map(s -> !s.startsWith("\"") ? s : s.substring(1, s.length() - 1)); //remove quotes
}

Following up, we now have a stream of strings, which need to be parsed into either a primitive or a string (since I'm assuming we don't have some weird form of object serialization):

private Object parse(String in) {
    //attempt to parse as number first. Any number can be parsed as a double/long
    try {
        return in.contains(".") ? Double.parseDouble(in) : Long.parseLong(in);
    } catch (NumberFormatException ex) {
        //it's not a number, so it's either a boolean or unparseable
        Boolean b = Boolean.parseBoolean(in); //if not a boolean, #parseBoolean is false
        b = in.toLowerCase().equals("false") && !b ? b : null; //so we map non-false to null
        return b != null ? b : in; //return either the non-null boolean or the string
    }
}

Using this, we can then convert our mixed stream to a mixed collection:

Set<Object> objs = this.parseStream(str1).map(this::parse).collect(Collectors.toSet());
Set<Object> comp = this.parseStream(str2).map(this::parse).collect(Collectors.toSet());
//we're using sets, keep in mind the nature of different collections and how they compare their elements here
if (objs.equals(comp)) {
    //we have a matching set
}

Lastly, an example of some sanity checks would be ensuring things like the appropriate braces are on the input string, etc. Despite what others said I learned the set syntax as {a, b, ...c}, and series/list syntax as [a, b, ...c], both of which have different comparisons here.

like image 178
Rogue Avatar answered Jul 15 '26 03:07

Rogue



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!