Простой способ найти, содержат ли два различных списка точно те же элементы?

Если вы боретесь с обнаружением событий изменения ориентации в диалоге НЕЗАВИСИМО ОТ ССЫЛКИ О ДЕЯТЕЛЬНОСТИ , этот метод работает потрясающе хорошо. Я использую это, потому что у меня есть свой собственный класс диалога, который может отображаться в нескольких различных действиях, поэтому я не всегда знаю, в каком действии он отображается. С этим методом вам не нужно изменять AndroidManifest, беспокойтесь о ссылках на действия, и вам не нужен пользовательский диалог (как у меня). Тем не менее, вам нужен пользовательский вид контента, чтобы вы могли обнаружить изменения ориентации, используя этот конкретный вид. Вот мой пример:

Настройка

public class MyContentView extends View{
    public MyContentView(Context context){
        super(context);
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig){
        super.onConfigurationChanged(newConfig);

        //DO SOMETHING HERE!! :D
    }
}

Реализация 1 - Диалог

Dialog dialog = new Dialog(context);
//set up dialog
dialog.setContentView(new MyContentView(context));
dialog.show();

Реализация 2 - AlertDialog.Builder

AlertDialog.Builder builder = new AlertDialog.Builder(context);
//set up dialog builder
builder.setView(new MyContentView(context));        //Can use this method
builder.setCustomTitle(new MycontentView(context)); // or this method
builder.build().show();

Реализация 3 - ProgressDialog / AlertDialog

ProgressDialog progress = new ProgressDialog(context);
//set up progress dialog
progress.setView(new MyContentView(context));        //Can use this method
progress.setCustomTitle(new MyContentView(context)); // or this method
progress.show();
232
задан Jacob van Lingen 25 March 2019 в 21:38
поделиться

6 ответов

Если вам важен порядок, просто используйте метод equals:

list1.equals(list2)

Из документации javadoc:

Сравнивает указанный объект с этот список для равенства. Возвращает истину тогда и только тогда, когда указанный объект также список, оба списка имеют одинаковые размер, и все соответствующие пары элементы в двух списках равны. (Два элемента e1 и e2 равны, если (e1 == null? e2 == null: e1.equals (e2)).) Другими словами, два списки считаются равными, если они содержат одинаковые элементы в одном порядок. Это определение гарантирует, что метод equals работает правильно в разных реализациях интерфейс List.

Если вы хотите проверять независимо от порядка, вы можете скопировать все элементы в Sets и использовать равные в результирующих наборах:

public static <T> boolean listEqualsIgnoreOrder(List<T> list1, List<T> list2) {
    return new HashSet<>(list1).equals(new HashSet<>(list2));
}

Ограничение этого подхода состоит в том, что он не только игнорирует порядок, но и также частота повторяющихся элементов. Например, если список1 был ["A", "B", "A"] и список2 был ["A", "B", "B"], то Подход Set будет рассматривать их как равные.

Если вам нужно быть нечувствительным к порядку, но чувствительным к частоте дублирования, вы можете:

339
ответ дан 23 November 2019 в 03:34
поделиться

Это зависит от того, какой конкретный класс List вы используете. В абстрактном классе AbstractCollection есть метод containsAll (Collection), который принимает другую коллекцию (List - это коллекция) и:

Возвращает true, если эта коллекция содержит все элементы в указанной коллекции.

Таким образом, если ArrayList передается, вы можете вызвать этот метод, чтобы проверить, совпадают ли они.

       List foo = new ArrayList();
    List bar = new ArrayList();
    String str = "foobar";

    foo.add(str);
    bar.add(str);

    foo.containsAll(bar);

Причина использования containsAll () заключается в том, что он выполняет итерацию по первому списку в поисках совпадения во втором списке. . Так что, если они не в порядке, equals () не подберет их.

РЕДАКТИРОВАТЬ: Я просто хочу прокомментировать здесь амортизированное время выполнения различных предлагаемых опций. Важно ли время бега? Конечно. Это единственное, что вам следует учитывать? Нет.

Копирование КАЖДОГО отдельного элемента из ваших списков в другие списки требует времени, а также требует значительного объема памяти (фактически удваивая объем используемой вами памяти).

Итак, если память в вашей JVM не вызывает беспокойства (что обычно должно быть), тогда вам все равно нужно учитывать время, необходимое для копирования каждого элемента из двух списков в два TreeSet. Помните, что он сортирует каждый элемент по мере его поступления.

Мой последний совет? Вам необходимо принять во внимание свой набор данных и количество элементов в вашем наборе данных, а также размер каждого объекта в вашем наборе данных, прежде чем вы сможете принять здесь правильное решение. Поиграйте с ними, создайте по одному в каждую сторону и посмотрите, какой из них работает быстрее. Это хорошее упражнение.

-2
ответ дан 23 November 2019 в 03:34
поделиться
list1.equals(list2);

Если ваш список содержит настраиваемый класс MyClass, этот класс должен переопределить функцию equals .

 class MyClass
  {
  int field=0;
  @0verride
  public boolean equals(Object other)
        {
        if(this==other) return true;
        if(other==null || !(other instanceof MyClass)) return false;
        return this.field== MyClass.class.cast(other).field;
        }
  }

Примечание: если вы хотите проверить равенство в java.util.Set, а не в java.util.List , тогда ваш объект должен переопределить функцию hashCode .

2
ответ дан 23 November 2019 в 03:34
поделиться

Это сделает метод equals в List, списки упорядочены, поэтому для равенства двух списков должны быть одинаковые элементы в одном порядке.

return list1.equals(list2);
2
ответ дан 23 November 2019 в 03:34
поделиться

Я написал кучу статей в комментариях, я думаю, что это требует своего собственного ответа.

Как все здесь говорят, использование equals () зависит от порядка. Если вас не волнует порядок, у вас есть 3 варианта:

Вариант 1

Используйте containsAll () . Этот вариант, на мой взгляд, не идеален, потому что он предлагает наихудшую производительность, O (n ^ 2).

Вариант 2

Есть два варианта этого:

2a) Если вы не используете не заботьтесь о поддержании порядка ваших списков ... используйте Collections.sort () в обоих списках. Затем используйте equals () . Это O (nlogn), потому что вы выполняете две сортировки, а затем сравнение O (n).

2b) Если вам нужно поддерживать порядок списков, вы можете сначала скопировать оба списка. ЗАТЕМ вы можете использовать решение 2a в обоих скопированных списках. Однако это может быть непривлекательно, если копирование стоит очень дорого.

Это приводит к:

Вариант 3

Если ваши требования такие же, как часть 2b , но копирование слишком дорого. Вы можете использовать TreeSet для сортировки за вас. Выгрузите каждый список в отдельный TreeSet. Он будет отсортирован в наборе, а исходные списки останутся нетронутыми. Затем выполните сравнение equals () на обоих TreeSet s. TreeSets могут быть построены за O (nlogn) времени, а equals () равно O (n).

Выберите: -).

EDIT : Я почти забыл о той же оговорке, которую указывает Лоуренс Гонсалвес . Реализация TreeSet устранит дубликаты. Если вас интересуют дубликаты, вам понадобится какой-то отсортированный мультимножество.

Вариант 3

Если ваши требования такие же, как часть 2b , но копирование слишком дорого. Вы можете использовать TreeSet для сортировки за вас. Выгрузите каждый список в отдельный TreeSet. Он будет отсортирован в наборе, а исходные списки останутся нетронутыми. Затем выполните сравнение equals () на обоих TreeSet s. TreeSets могут быть построены за O (nlogn) времени, а equals () равно O (n).

Выберите: -).

EDIT : Я почти забыл о той же оговорке, которую указывает Лоуренс Гонсалвес . Реализация TreeSet устранит дубликаты. Если вас интересуют дубликаты, вам понадобится какой-то отсортированный мультимножество.

Вариант 3

Если ваши требования такие же, как часть 2b , но копирование слишком дорого. Вы можете использовать TreeSet для сортировки за вас. Выгрузите каждый список в отдельный TreeSet. Он будет отсортирован в наборе, а исходные списки останутся нетронутыми. Затем выполните сравнение equals () на обоих TreeSet s. TreeSets могут быть построены за O (nlogn) времени, а equals () равно O (n).

Выберите: -).

EDIT : Я почти забыл о той же оговорке, которую указывает Лоуренс Гонсалвес . Реализация TreeSet устранит дубликаты. Если вас интересуют дубликаты, вам понадобится какой-то отсортированный мультимножество.

Вы можете использовать TreeSet для сортировки за вас. Выгрузите каждый список в отдельный TreeSet. Он будет отсортирован в наборе, а исходные списки останутся нетронутыми. Затем выполните сравнение equals () на обоих TreeSet s. TreeSets могут быть построены за O (nlogn) времени, а equals () равно O (n).

Выберите: -).

EDIT : Я почти забыл о той же оговорке, которую указывает Лоуренс Гонсалвес . Реализация TreeSet устранит дубликаты. Если вас интересуют дубликаты, вам понадобится какой-то отсортированный мультимножество.

Вы можете использовать TreeSet для сортировки за вас. Выгрузите каждый список в отдельный TreeSet. Он будет отсортирован в наборе, а исходные списки останутся нетронутыми. Затем выполните сравнение equals () на обоих TreeSet s. TreeSets могут быть построены за O (nlogn) времени, а equals () равно O (n).

Выберите: -).

EDIT : Я почти забыл о той же оговорке, которую указывает Лоуренс Гонсалвес . Реализация TreeSet устранит дубликаты. Если вас интересуют дубликаты, вам понадобится какой-то отсортированный мультимножество.

TreeSets могут быть построены за O (nlogn) времени, а equals () равно O (n).

Выберите: -).

EDIT : Я почти забыл о той же оговорке, которую указывает Лоуренс Гонсалвес . Реализация TreeSet устранит дубликаты. Если вас интересуют дубликаты, вам понадобится какой-то отсортированный мультимножество.

TreeSets могут быть построены за O (nlogn) времени, а equals () равно O (n).

Выберите: -).

EDIT : Я почти забыл о той же оговорке, которую указывает Лоуренс Гонсалвес . Реализация TreeSet устранит дубликаты. Если вас интересуют дубликаты, вам понадобится какой-то отсортированный мультимножество.

89
ответ дан 23 November 2019 в 03:34
поделиться
Другие вопросы по тегам:

Похожие вопросы: