6

I have two List<String[]>'s (string array lists), and I'd like to match the contents with each other. Obviously == doesn't do the trick, but .equals () doesn't seem to do it either. So how should I check whether the contents of the string array lists are the same?

By the way, in both above cases I got an exception with message null.

EDIT: Ok... for some reason only x.equals(y) works, and not y.equals(x). Odd...

Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
RobinJ
  • 5,022
  • 7
  • 32
  • 61
  • Can you provide a code snippet of what you have tried? – kosa Sep 07 '12 at 18:17
  • "I got an exception with message **null** ... for some reason only x.equals (y) works, and **not y.equals (x)**." I believe `y` is `null`, do you ever initialize it? – Sam Sep 07 '12 at 18:20
  • +Sam I do, right after `public class MainActivity extends Activity {`. – RobinJ Sep 07 '12 at 18:21
  • Please post the relevant code, if you are receiving NullPointerExceptions then you are _defining_ but not _initializing_ something. (Also you'll want to use `@username` instead of `+username` in SO to notify a particular user.) – Sam Sep 07 '12 at 18:24
  • Where exactly are you getting a null exception? Maybe you need to make sure y is not null before y.equals(x). For example if(y!=null && y.equals(x) || y==null && x==null) { ... – Jorge Cevallos Sep 07 '12 at 18:44
  • Ok... I was about to accept the first answer... Only where the hell did that answer poof to? – RobinJ Sep 07 '12 at 18:45
  • Whoever mass-downvoted almost all answers, please explain your rational. – Paul Bellora Sep 07 '12 at 18:54

5 Answers5

5

Perhaps the easiest solution would be to use two List<List<String>>s instead. Assuming the List implementations used extend AbstractList, using equals will give you the desired behavior. From the documentation for AbstractList.equals:

Compares the specified object with this list for equality. Returns true if and only if the specified object is also a list, both lists have the same size, and all corresponding pairs of elements in the two lists are equal. (Two elements e1 and e2 are equal if (e1==null ? e2==null : e1.equals(e2)).) In other words, two lists are defined to be equal if they contain the same elements in the same order.

You can easily wrap a String[] in a thin List<String> implementation that extends AbstractList by using Arrays.asList.

EDIT: Here's an example:

String[] array1 = {"1", "2", "3"};
String[] array2 = {"4", "7"};

String[] array3 = {"1", "2", "3"};
String[] array4 = {"4", "7"};

List<List<String>> lst1 = new ArrayList<>();
lst1.add(Arrays.asList(array1));
lst1.add(Arrays.asList(array2));

List<List<String>> lst2 = new ArrayList<>();
lst2.add(Arrays.asList(array3));
lst2.add(Arrays.asList(array4));

System.out.println(lst1.equals(lst2)); //prints true
Paul Bellora
  • 54,340
  • 18
  • 130
  • 181
3

Typically you should avoid dealing with Arrays. they are ugly and lead to these kind of problems. If possible use List<List<String>> then you can use .equals() normally.

if you insist, you could use a custom isequal implementation like below. the key is to use Arrays.equals()

public class DemoEquals {
    List<String[]> listOne = (List<String[]>) Arrays.asList(new String[]{"one1", "one2"}, new String[]{"two1"});
    List<String[]> listOneOne = (List<String[]>) Arrays.asList(new String[]{"one1", "one2"}, new String[]{"two1"});
    List<String[]> listTwo = (List<String[]>) Arrays.asList(new String[]{"2one1", "2one2"}, new String[]{"2two1"});

    private boolean isEqual(List<String[]> list1, List<String[]> list2) {
        if (list1.size() != list2.size()) return false;
        for (int i = 0; i < list1.size(); i++) {
            if (!Arrays.equals(list1.get(i), list2.get(i))) return false;
        }
        return true;
    }
    @SuppressWarnings("unchecked")
    private void isEqual() {
        //prints true
        System.out.println(isEqual(Collections.EMPTY_LIST, Collections.EMPTY_LIST));
        //prints true
        System.out.println(isEqual(listOne, listOne));
        //prints true
        System.out.println(isEqual(listOne, listOneOne));
        //prints false
        System.out.println(isEqual(listOne, listTwo));
        //prints false
        System.out.println(isEqual(listOne, Collections.EMPTY_LIST));

    }
    public static void main(String[] args) {
        new DemoEquals().isEqual();
    }
}
Joseph Erickson
  • 2,304
  • 20
  • 29
Andreas Petersson
  • 16,248
  • 11
  • 59
  • 91
0

You can use the INTERFACE Comparable. Implement the needed method and you can use the List1.compare(List2) function.

zeyorama
  • 444
  • 3
  • 12
0

Just .equals() works fine, but somehow only in one direction.

I was going to accept the first answer on this question, but apparently the guy removed his answer.

RobinJ
  • 5,022
  • 7
  • 32
  • 61
  • if it works in one direction its not working. you are creating a bug here that will haunt you later. both @Paul Bellora and my answer are fine stick with one of them – Andreas Petersson Sep 09 '12 at 19:51
-1

Using Jon Skeet's answer of how to convert a List to a String (using Guava), another option would be to convert the 2 lists to 2 strings and then compare them using equals. No looping.

Community
  • 1
  • 1
atrain
  • 9,139
  • 1
  • 36
  • 40