Одинаковые элементы массива

1

Я хочу проверить, все ли элементы в одном массиве такие же, как и все элементы в другом массиве, т.е. Один к одному. (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() не работает, поскольку есть дубликаты.

Теги:
arrays

7 ответов

1
Лучший ответ

Это будет короткое решение вашей проблемы. Я уверен, что для этого есть более эффективные, но сложные методы. Здесь 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);
}

Можно оптимизировать его с помощью проверки размера, чтобы избежать сортировки.

  • 0
    Оставьте вопрос дублирования вместе, пожалуйста, смотрите отредактированный вопрос.
  • 1
    Обновил мой ответ, чтобы рассмотреть вопрос о дублировании. Кстати, первый дизайн был намеренным, потому что вы проверили не дублирования (list.contains) в ваших примерах.
Показать ещё 3 комментария
1

Для этого вы можете использовать следующее:

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.

  • 0
    Оставьте вопрос дублирования вместе, пожалуйста, смотрите отредактированный вопрос.
1

Вы можете использовать хеш-карту. Этот метод имеет более низкую временную сложность, поскольку сортировка и поиск не требуются, но используется более высокая сложность пространства в качестве хэш-карты:

        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.
Этот метод также учитывает повторяющиеся строки во входных массивах.

  • 0
    хорошо сделано для выявления проблемы дублирования. Хорошие усилия на примере, и я вижу, как это работает. Хотя я ищу что-то с меньшим количеством кодирования и большим использованием предоставленных библиотек.
1

Используйте Arrays.equals:

Arrays.equals(ary, ary2));

Или Arrays.deepEquals

Возвращает 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.

  • 0
    элементы массива не находятся в том же порядке, что и другие.
1
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[]) этот метод подходит для использования с вложенными массивами произвольной глубины.

  • 0
    элементы массива расположены не в том же порядке, что и другие.
1

Вы можете использовать метод listAllAll

strList2.removeAll(strList1)

if(strList2.isEmpty)
{
  // Exact match
}
else{

  // failed
}
  • 0
    это хороший из коробки способ сделать это. было бы немного сложно по производительности, хотя.
  • 2
    Это не правильно. Если strList2 является подмножеством strList1, тогда strList2.removeAll (strList1) приведет к пустому списку, но это определенно не точное совпадение.
Показать ещё 2 комментария
1
public static boolean equals(int[] a, int[] a2)

Возвращает true, если два указанных массива ints равны друг другу. Два массива считаются равными, если оба массива содержат одинаковое количество элементов, а все соответствующие пары элементов в двух массивах равны. Другими словами, два массива равны, если они содержат одни и те же элементы в одном порядке. Кроме того, две ссылки на массивы считаются равными, если оба значения равны нулю.

  • 0
    они два элемента массива не в том же порядке.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню