Checking containment in a Set of strings in Java

21,715

Solution 1

Your guess is correct: arrays ([]) do not implement a deep equals method: they are equals if they are the same instance.

The simplest solution would be: replacing String[] by List<String>

An other way (but i do not recommend it) is to implement your own Set, which does not based on Object.equals but on java.util.Arrays.equals(Object[]a, Object[]b)

Solution 2

Convert that String[] to List<String> and it should work out pretty well.

Set<List<String>> s  = new HashSet<List<String>>();
s.add(Arrays.asList("lucy", "simon"));
System.out.println(s.contains(Arrays.asList("lucy", "simon")));

Solution 3

Can the elements of the String[] be in different orders and still make the whole array be considered equal to another array containing the same elements in another order? If yes, you'd indeed be better off implementing a container class and overriding equals and hashcode.

if not, and if storing the internal elements as Lists instead of arrays is an acceptable alternative, then you could do this:

package com.stackoverflow;


import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class StringContainment {

  public static void main(final String[] args) {
    final Set<String[]> s = new HashSet<String[]>();
    final Set<List<String>> s2 = new HashSet<List<String>>();

    s.add(new String[] {"lucy", "simon"});
    s2.add(Arrays.asList(new String[] { "lucy", "simon" }));

    System.out.println(s.contains(new String[] {"lucy", "simon"})); // false
    System.out.println(s2.contains(Arrays.asList(new String[] {"lucy", "simon"}))); // true
  }

}

The first check will return false, the second true. Might be easier that way if you can use lists.

If you can't, you could still use this as long as you don't need to do this comparison too often (it's definitely not a good idea performance-wise).

Solution 4

Sounds like you've already answered your question. One option is as you already stated. The another would be to use Set>, since the API for equals(Object) says:

Compares the specified object with this collection for equality.

Solution 5

Use Set<Set<String>> or Set<List<String>> instead of Set<String[]>

Code:

List<String> s1=Arrays.asList("1","2"),s2=Arrays.asList("1","2");
System.out.println(s1.equals(s2) + " "+s1.hashCode()+ " "+s2.hashCode());

Output:

true 2530 2530
Share:
21,715
athena
Author by

athena

Updated on March 07, 2020

Comments

  • athena
    athena over 4 years

    I have a Set of String[]. I want to check whether this Set contains another String[].

    Set<String[]> s  = new HashSet<String[]>();
    s.add(new String[] {"lucy", "simon"});
    System.out.println(s.contains(new String[] {"lucy", "simon"}));
    

    However, false is printed. My guess is this is because only the references are being compared and not the actual Strings. It seems, the only option I have is to create a class, say Phrase, and implement hashCode() and equals() (that use Arrays.hashCode(...)).

    Is there any other way to achieve what I want?