Есть какие-то способы сделать это? Я искал, но не нашел.
Другой вопрос: мне нужны эти методы, чтобы можно было фильтровать файлы. Некоторые из них являются AND
фильтрами, а некоторые - OR
фильтрами (например, в теории множеств), поэтому мне нужно фильтровать по всем файлам, и объединить / пересечь списки ArrayLists, которые содержат эти файлы.
Следует ли мне использовать другую структуру данных для хранения файлов? Есть ли что-нибудь еще, что могло бы улучшить время выполнения?
java
list
union
intersection
yotamoo
источник
источник
Vector
? Этот класс не поощрялся начиная с Java 1.2.Vector
- это взаимодействие между потоками, но есть и более безопасные структуры данных для этих случаев использования. См. Также этот вопрос . НаVector
мой взгляд, любые библиотеки, которые все еще используются в 2016 году, вызывают большие подозрения.Ответы:
Вот простая реализация без использования сторонней библиотеки. Основное преимущество перед
retainAll
,removeAll
и вaddAll
том , что эти методы не изменяют первоначальные списки вклада методов.источник
HashSet
для,intersection
чтобы средняя производительность для случая была O (n) вместо O (n ^ 2).Коллекция (так что и ArrayList) имеет:
Используйте реализацию List, если вы принимаете повторы, и реализацию Set, если вы этого не сделаете:
источник
HashSet
вместо этого использовать .addAll()
происходит объединение списков; он просто присоединяет второй список к концу первого. Операция объединения позволит избежать добавления элемента, если первый список уже содержит его.Этот пост довольно старый, но тем не менее он был первым, который появился в Google при поиске этой темы.
Я хочу дать обновление, используя потоки Java 8, выполняющие (в основном) то же самое в одной строке:
Если у кого-то есть лучшее / более быстрое решение, дайте мне знать, но это решение - хороший лайнер, который можно легко включить в метод, не добавляя ненужный вспомогательный класс / метод, при этом сохраняя читабельность.
источник
Set
затем используйте метод набораcontains
. Не все в жизни нужно делать потоками.союз будет
removeAll
и тогдаaddAll
.Дополнительные сведения см. В документации коллекции (ArrayList - это коллекция) http://download.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html
источник
retainAll()
иremoveAll()
являются операциями O (n ^ 2) над списками. Мы можем сделать лучше.retainAll
из {1, 2, 2, 3, 4, 5} по {1, 2, 3} приводит к {1, 2, 2, 3}. Разве это не должно быть перекрестком {1, 2, 3}?Союзы и пересечения определены только для множеств, а не списков. Как вы упомянули.
Проверьте библиотеку guava на наличие фильтров. Также гуава обеспечивает реальные пересечения и союзы
источник
Вы можете использовать
CollectionUtils
с Apache Commons .источник
Отмеченное решение неэффективно. Он имеет временную сложность O (n ^ 2). Что мы можем сделать, так это отсортировать оба списка и выполнить алгоритм пересечения, как показано ниже.
У этого есть сложность O (n log n + n), которая находится в O (n log n). Аналогичным образом производится объединение. Просто убедитесь, что вы внесли подходящие изменения в операторы if-elseif-else.
Вы также можете использовать итераторы, если хотите (я знаю, что они более эффективны в C ++, я не знаю, верно ли это и в Java).
источник
contains()
в цикле (как предлагает Devenv) займет время O (n + m). Сортировка излишне сложна и занимает O (n log n + m log n + n) времени. Конечно, это сокращает время до O (n log n), но это все еще хуже, чем линейное время, и намного сложнее.Я думаю, вам следует использовать a
Set
для хранения файлов, если вы хотите пересечь и объединить их. Затем вы можете использовать гуавы «s Устанавливает класс делатьunion
,intersection
и фильтрацию поPredicate
а. Разница между этими методами и другими предложениями заключается в том, что все эти методы создают ленивые представления объединения, пересечения и т. Д. Двух наборов. Apache Commons создает новую коллекцию и копирует в нее данные.retainAll
изменяет одну из ваших коллекций, удаляя из нее элементы.источник
Вот способ пересечения потоков (помните, что для потоков нужно использовать java 8):
Пример для списков разных типов. Если у вас есть связь между foo и bar и вы можете получить объект bar из foo, чем вы можете изменить свой поток:
источник
Я нашел ListUtils очень полезным для этого случая использования.
Используйте ListUtils из org.apache.commons.collections, если вы не хотите изменять существующий список.
ListUtils.intersection(list1, list2)
источник
Вы можете использовать commons-collections4 CollectionUtils
источник
В Java 8 я использую простые вспомогательные методы вроде этого:
источник
Если объекты в списке являются хешируемыми (т.е. имеют приличный hashCode и функцию равенства), самый быстрый подход между таблицами прибл. size> 20 - это создать HashSet для большего из двух списков.
источник
Я также работал над подобной ситуацией и обратился сюда за помощью. В итоге я нашел собственное решение для массивов. ArrayList AbsentDates = новый ArrayList (); // Сохраним Array1-Array2
Примечание. Отправьте это сообщение, если это может помочь кому-то обратиться за помощью к этой странице.
источник
Пересечение двух списков разных объектов на основе общего ключа - Java 8
источник
JDK8 + (вероятно, лучшая производительность)
Если вам не важна производительность и вы предпочитаете меньший код, просто используйте:
источник
Окончательное решение:
источник
Сначала я копирую все значения массивов в один массив, а затем удаляю повторяющиеся значения в массив. Строка 12, объясняющая, если одно и то же число встречается чаще, чем раз, то помещает дополнительное мусорное значение в позицию «j». В конце перейдите от начала к концу и проверьте, возникает ли такое же значение мусора, а затем отбросьте.
источник
ArrayList
, для хранения результата объединения.Integer
а неint
. Тогда вы можете использоватьnull
вместо своего «мусорное значение». «Мусорные значения» или «контрольные значения» обычно плохая идея, потому что эти значения могут все еще присутствовать во входных данных.После тестирования вот мой лучший подход к пересечению.
Более высокая скорость по сравнению с чистым подходом HashSet. Приведенные ниже HashSet и HashMap имеют одинаковую производительность для массивов с более чем 1 миллионом записей.
Что касается подхода Java 8 Stream, скорость довольно низкая для массива размером более 10 КБ.
Надеюсь, это поможет.
источник
Метод keepAll () используется для поиска общего элемента. т.е .; пересечение list1.retainAll (list2)
источник
Если у вас есть данные в наборах, вы можете использовать
Sets
класс Guava .источник
Если число совпадает, чем я проверяю, это происходит в первый раз или нет с помощью "indexOf ()", если число совпадает в первый раз, затем распечатайте и сохраните в строке, чтобы при следующем совпадении того же числа оно было выиграно ' t печать, потому что из-за "indexOf ()" условие будет ложным.
}
источник