Я хочу проверить, все ли элементы в одном массиве такие же, как и все элементы в другом массиве, т.е. Один к одному. (NB: два элемента массива не будут находиться в одном порядке друг с другом)
Есть ли быстрый способ сделать это или уже существующую библиотеку, которую я могу использовать?
В настоящее время два способа, о которых я могу думать, не очень хороши:
совпадают один за другим (Edit 3: этот пример неверен, не поддерживает дубликаты)
boolean exactMatch = true;
if(strList1.size() == strList2.size()){
for(String str: StrList1){
if(!strList2.contains(str)){
exactMatch = false;
break;
}
}
}
сортировать, затем сопоставлять (более оптимизированный, esp для больших массивов)
strList1 = Arrays.sort(strList1);
strList2 = Arrays.sort(strList2);
boolean exactMatch = true;
if(strList1.size() == strList2.size()){
for (int i = 0; i < strList1.length; i++) {
if(!strList1[i].equals(strList2[i])){
exactMatch = false;
break;
}
}
}
Редактировать 1
Спасибо за тех, кто дал комментарии. Элементы массива не находятся в одном порядке друг с другом. т.е. следующее возвращает false:
String[] strList1 = {"ABC", "CDE", "EFG"};
String[] strList2 = {"ABC", "EFG", "CDE"};
System.out.println("array equals " + Arrays.deepEquals(strList1, strList2));
Изменить 2
Один хороший момент, о котором я забыл, указывает, что "myusuf" указывает на дубликаты в массиве. Это означает, что мой пример "Match One By One" не будет работать. Возьмите это, например:
public static void main(String[] args) {
String[] strList1 = {"ABC", "CDE", "EFG", "ABC"};
String[] strList2 = {"ABC", "EFG", "CDE", "CDE"};
System.out.println(arrayEquals(strList1,strList2));
}
private static boolean arrayEquals(String[] array1, String[] array2) {
List<String> list1 = Arrays.asList(array1);
List<String> list2 = Arrays.asList(array2);
return list1.containsAll(list2) && list2.containsAll(list1);
}
В этом случае strList1 имеет дубликат для "ABC", а strList2 имеет дубликат для "CDE", но они по-прежнему совпадают, потому что их уникальные элементы все те же, когда массив сам отличается.
Редактировать 3
Спасибо всем, кто ответил. Таким образом, после многого назад и вперед, кажется, самый короткий способ сделать это:
String[] strList1 = {"ABC", "CDE", "EFG", "CDE", "EFG"};
String[] strList2 = {"ABC", "EFG", "CDE", "EFG", "CDE"};
Arrays.sort(strList1);
Arrays.sort(strList2);
boolean exactMatch = Arrays.deepEquals(strList1, strList2);
System.out.println("test3 - match: " + exactMatch);
Я надеялся на один вызов метода, который мог бы все это сделать, но, похоже, это сделано. Arrays.deepEquals() работает только с отсортированными массивами, если все элементы различаются по порядку. Подход с contains() не работает, поскольку есть дубликаты.
Это будет короткое решение вашей проблемы. Я уверен, что для этого есть более эффективные, но сложные методы. Здесь arrayEquals
преобразует ваши массивы в List
и использует List.containsAll
для проверки равенства.
public class ArrayEquality {
public static void main(String[] args) {
String[] array1 = {"test1","test2"};
String[] array2 = {"test2","test1"};
String[] array3 = {"test2","test3"};
String[] strList1 = {"ABC", "CDE", "EFG"};
String[] strList2 = {"ABC", "EFG", "CDE"};
System.out.println(arrayEquals(array1,array2));
System.out.println(arrayEquals(array2,array3));
System.out.println(arrayEquals(strList1,strList2));
}
//ARRAY EQUALITY CHECK
private static boolean arrayEquals(String[] array1, String[] array2) {
List<String> list1 = Arrays.asList(array1);
List<String> list2 = Arrays.asList(array2);
return list1.containsAll(list2) && list2.containsAll(list1);
}
}
Для решения дубликатов в этом решении массивEquals можно изменить следующим образом:
private static boolean arrayEquals(String[] array1, String[] array2) {
List<String> list1 = Arrays.asList(array1);
List<String> list2 = Arrays.asList(array2);
Collections.sort (list1);
Collections.sort (list2);
return list1.equals(list2);
}
Можно оптимизировать его с помощью проверки размера, чтобы избежать сортировки.
Для этого вы можете использовать следующее:
String[] strArray1;
String[] strArray2;
Я переименовал их в strArray
вместо strList
для логичности, а затем:
private <T> boolean containsAll(final T[] a1, final T[] a2) {
return Arrays.asList(a1).containsAll(Arrays.asList(a2));
}
и назовите его:
boolean exactMath = containsAll(strArray1, strArray2)
&& containsAll(strArray2, strArray1);
Обратите внимание, что Arrays.asList(T[] array)
создает оболочку List<T>
вокруг T[] array
, на самом деле она не делает копию T[] array
. Если вы измените List<T>
, он также изменит T[] array
.
Вы можете использовать хеш-карту. Этот метод имеет более низкую временную сложность, поскольку сортировка и поиск не требуются, но используется более высокая сложность пространства в качестве хэш-карты:
String[] strList1 = {"ABC", "CDE", "EFG"};
String[] strList2 = {"ABC", "EFG", "CDE"};
Boolean flag = true;
Map<String, Integer> map = new HashMap<String, Integer>();
/*Initial Check*/
if(strList1.length != strList2.length) {
System.out.print("Array equals: false");
return 0;
}
/*Add all strings from list1 and their frequency to map*/
for(int i=0; i<strList1.length;i++) {
if(map.get(strList1[i]) != null)
map.put(strList1[i], map.get(strList1[i]) + 1);
else
map.put(strList1[i], 0);
}
/*If string found in map from list2, decrement count in map
else list2 contains a string not in map, then arrays
unequal as list2 contains a string not in list1*/
for(int i=0; i<strList2.length;i++) {
if(map.get(strList2[i]) != null)
map.put(strList2[i], map.get(strList2[i]) - 1);
else {
System.out.print("Array equals: false");
flag = false;
}
}
/*If map contains the same value for every string i.e. 0, then they occur
equal no. of times in both arrays. Hence, Set values will contain
only one value so (values.size() == 1) will be equal true, else false*/
if(flag) {
Set<Integer> values = new HashSet<Integer>(map.values());
System.out.print("Array equals: " + (values.size() == 1));
}
return 0;
Для вашего ввода это будет выводиться: Array equals: true
.
Этот метод также учитывает повторяющиеся строки во входных массивах.
Используйте Arrays.equals:
Arrays.equals(ary, ary2));
Возвращает true, если два указанных массива глубоко равны друг другу. В отличие от метода @link {#equals {Object [], Object []), этот метод подходит для использования с вложенными массивами произвольной глубины. Две ссылки на массивы считаются глубоко равными, если оба они являются нулевыми или относятся к массивам, которые содержат одинаковое количество элементов, и все соответствующие пары элементов в двух массивах глубоко равны.
Два, возможно, нулевые элементы e1 и e2 являются глубоко равными, если выполнено одно из следующих условий:
e1 и e2 - оба массива типов ссылочных объектов, а
Arrays.deepEquals(e1, e2)
вернетtrue
e1 и e2 - массивы одного и того же примитивного типа, и соответствующая перегрузкаArrays.equals(e1, e2)
вернетtrue
.
e1 == e2
e1.equals(e2) вернет true.
Arrays#deepEquals(java.lang.Object[], java.lang.Object[])
Он обеспечивает, что ссылки на два массива считаются глубоко равными или нет.
Arrays.deepEquals(e1,e2);
Два, возможно, нулевые элементы e1 и e2 являются глубоко равными, если выполнено одно из следующих условий:
- e1 and e2 are both arrays of object reference types, and Arrays.deepEquals(e1, e2) would return true - e1 and e2 are arrays of the same primitive type, and the appropriate overloading of Arrays.equals(e1, e2) would return true. - e1 == e2 - e1.equals(e2) would return true. Note that this definition permits null elements at any depth.
В отличие от метода Arrays#equals(Object[],Object[])
этот метод подходит для использования с вложенными массивами произвольной глубины.
Вы можете использовать метод listAllAll
strList2.removeAll(strList1)
if(strList2.isEmpty)
{
// Exact match
}
else{
// failed
}
public static boolean equals(int[] a, int[] a2)
Возвращает true, если два указанных массива ints равны друг другу. Два массива считаются равными, если оба массива содержат одинаковое количество элементов, а все соответствующие пары элементов в двух массивах равны. Другими словами, два массива равны, если они содержат одни и те же элементы в одном порядке. Кроме того, две ссылки на массивы считаются равными, если оба значения равны нулю.