如何测试String数组列表的相等性

时间:2014-01-26 15:40:27

标签: java list collections equals

我想我看不到森林中的树...我如何在String数组列表中递归测试所有元素的相等(不是同一性)?这是一个最小的例子:

List<String[]> left = new ArrayList<>();
left.add(new String[]{"one", "two"});

List<String[]> right = new ArrayList<>();
right.add(new String[]{"one", "two"});

System.out.println(left.equals(right) ? "Yeah!" : "This is not what I want.");

我想在单元测试中使用它。

更多上下文:我有一个包含多个字段的类,其中一些是List String个数组,有些是SetString数组。该类是解析器的结果(实际上是解析器级联中的中间步骤)。为了测试解析器,我想检查相关类的实例是否相等。 IDE自动生成的equals实现在几个Objects.equalsList<String[]>字段上使用了一系列Set<String[]>次调用,这是---所以我认为 - 相当于我在上面提供的最小例子。

6 个答案:

答案 0 :(得分:3)

测试两个列表的大小是否相同。然后,如果他们这样做,则迭代它们,并使用Arrays.equals()比较每对数组。

如果你有一个列表列表(List<List<String>>)会更容易,因为可以直接使用equals()来比较列表。

答案 1 :(得分:1)

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.text.html.HTMLDocument.Iterator;


public class test 
{
  public static void main(String args[])
  {

      List<String[]> left = new ArrayList<String[]>();
      left.add(new String[]{"one", "two"});

      List<String[]> right = new ArrayList<String[]>();
      right.add(new String[]{"one", "two"});

      java.util.Iterator<String[]> leftIterator =left.iterator();
      java.util.Iterator<String[]> rightIterator =right.iterator();
      if(left.size() !=right.size())   System.out.println("not equal");
      for(;leftIterator.hasNext();)
      {
         if(Arrays.equals(leftIterator.next(), rightIterator.next())) continue;
         else
         {
             System.out.print("not equal");
             break;
         }
      }


  }
}

答案 2 :(得分:1)

您想要比较每个列表,使用布尔值跟踪它们是否相等。我不知道会直接为你做这个功能。

    List<String[]> left = new ArrayList<>();
    left.add(new String[]{"one", "two"});

    List<String[]> right = new ArrayList<>();
    right.add(new String[]{"one", "two"});

    boolean isEqual = true;
    if (left.size() == right.size())
    {
        // Test for equality
        for (int i = 0; i < left.size(); i++)
        {
            // Compare each array in the list
            if (!Arrays.equals(leftArray, rightArray))
            {
                isEqual = false;
                break;
            }
        }
    }
    else
    {
        // The two list are not even the same length, so are not equal.
        isEqual = false;
    }

    System.out.println(isEqual ? "Yeah!" : "This is not what I want.");

答案 3 :(得分:1)

感谢大家的投入。这是我的结果代码。

protected static boolean equalsCollectionOfArrays(Collection<? extends Object[]> leftCollection,
                                                   Collection<? extends Object[]> rightCollection) {
    if (leftCollection.size() != rightCollection.size()) {
        return false;
    } else {
        Iterator<? extends Object[]> left = leftCollection.iterator();
        Iterator<? extends Object[]> right = rightCollection.iterator();
        while (left.hasNext()) {
            if (!Arrays.equals(left.next(), right.next())) {
                return false;
            }
        }
        return true;
    }
}

protected static int hashCodeCollectionOfArrays(Collection<? extends Object[]> collection) {
    int hash = 3;
    for (Object[] objects : collection) {
        hash = 67 * hash + Arrays.hashCode(objects);
    }
    return hash;
}

事实证明,我的问题并不仅限于List<String[]>,但我遇到了与Set<String[]>hashCode()相同的问题。我最终将这两种方法纳入了课程“equalshashCode”。通用通配符不是必需的(只有String数组),但我只是想通过学习基础课的方式来了解我对泛型的理解。

我正在考虑将来避免使用数组。任何评论都非常欢迎。

答案 4 :(得分:0)

如果您需要比较列表,请尝试使用该特定列表实例的equals(),提供另一个列表实例进行比较。

如果您需要比较数组,请尝试使用Arrays.equals()

如果您在测试方法org.junit.Assert assertArrayEquals()assertEquals()中执行此操作,那么他们将会调用这些方法。

答案 5 :(得分:0)

Java文档要求列表equals()在您使用时表现良好,因此如果List Listsboolean equals(Object o),您的代码就会有效:

  

Object

     

将指定对象与此列表进行比较以获得相等性。当且仅当指定的对象也是列表时,返回true,两个列表具有相同的大小,并且两个列表中的所有对应元素对都相等。 (如果(e1 == null?e2 == null:e1.equals(e2)),则两个元素e1和e2相等。)换句话说,如果两个列表包含相同顺序的相同元素,则它们被定义为相等。此定义确保equals方法在List接口的不同实现中正常工作。

然而,在“叶子”中你有普通的Java数组。这些将使用equals的{​​{1}}定义,它定义参考标识,而不是值相等。

在测试中解决这个问题的一种方法是编写一个小助手工厂例程,该例程接受String的变量参数列表并生成List返回以替换当前使用的Java数组。那么一切都应该工作正常。你的例子看起来像这样:

// A little helper to avoid the awkward syntax
// Arrays.asList(new String [] { "one", "two" })
public static List<String> listOf(String ... strings) {
    return Arrays.asList(strings);
}

public static void main(String[] args) {
    List<List<String>> left = new ArrayList<>();
    left.add(listOf("one", "two"));

    List<List<String>> right = new ArrayList<>();
    right.add(listOf("one", "two"));

    System.out.println(left.equals(right) ? "Yeah!" : "This is not what I want.");
}