Reputation: 5709
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?
Upvotes: 9
Views: 25575
Reputation: 15413
With Java8 stream introduction you can do it the following way:
Boolean res = s.stream()
.anyMatch(elm -> elm.equals("lucy") || elm.equals("simon"));
Upvotes: 0
Reputation: 22663
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).
Upvotes: 3
Reputation: 13789
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
Upvotes: 1
Reputation: 9110
I'd just loop through and call Arrays.equals:
something like this:
boolean contains(Set<String[]> s, String[] item) {
for(String[] toCompare: s) {
if(Arrays.equals(toCompare, item)) {
return true;
}
}
return false;
}
not sure if it's the fastest but it should do the job nicely
Upvotes: 0
Reputation: 687
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.
Upvotes: 1
Reputation: 120811
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)
Upvotes: 13
Reputation: 23208
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")));
Upvotes: 12