Ответы:
Если вам не нужны дубликаты в a Collection
, вам следует подумать, почему вы используете a, Collection
который разрешает дубликаты. Самый простой способ удалить повторяющиеся элементы - это добавить содержимое в Set
(что не допустит дублирования), а затем добавить Set
обратно в ArrayList
:
Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);
Конечно, это разрушает порядок элементов в ArrayList
.
public Set<Object> findDuplicates(List<Object> list) { Set<Object> items = new HashSet<Object>(); Set<Object> duplicates = new HashSet<Object>(); for (Object item : list) { if (items.contains(item)) { duplicates.add(item); } else { items.add(item); } } return duplicates; }
List
и Set
(вместо типов реализации ArrayList
и HashSet
как в вашем примере).
new HashSet(al)
вместо инициализации его пустым и вызывая addAll
.
Object
имеет несколько значений, если два из них повторяются, я считаю их дубликатами (другие значения могут отличаться) и использую Set
?
Несмотря на то, преобразуя ArrayList
к HashSet
эффективно удаляет дубликаты, если вам нужно , чтобы сохранить порядок вставки, я предпочел бы предложить вам использовать этот вариант
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
Затем, если вам нужно вернуть List
ссылку, вы можете снова использовать конструктор преобразования.
В Java 8:
List<String> deduped = list.stream().distinct().collect(Collectors.toList());
Обратите внимание, что для правильной работы фильтрации следует соблюдать контракт hashCode-equals для членов списка.
addAll
к которому вы можете new TreeSet<String>(String.CASE_INSENSITIVE_ORDER)
. Первый добавленный элемент останется в наборе, поэтому, если ваш список содержит «Dog» и «Dog» (в этом порядке), он TreeSet
будет содержать «Dog». Если порядок должен быть сохранен, то перед строкой в ответе поставить list.replaceAll(String::toUpperCase);
.
Предположим, у нас есть список String
как:
List<String> strList = new ArrayList<>(5);
// insert up to five items to list.
Затем мы можем удалить дубликаты элементов несколькими способами.
List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));
Примечание: если мы хотим сохранить порядок вставки, нам нужно использовать LinkedHashSet
вместоHashSet
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());
Примечание. В случае, если мы хотим собрать результат в конкретной реализации списка, например, LinkedList
тогда мы можем изменить приведенный выше пример следующим образом:
List<String> deDupStringList3 = strList.stream().distinct()
.collect(Collectors.toCollection(LinkedList::new));
Мы можем использовать parallelStream
также в приведенном выше коде, но он может не дать ожидаемых преимуществ производительности. Проверьте этот вопрос для получения дополнительной информации.
parallel streams
это всегда даст лучшую производительность. Но это миф. Позже я узнал, что есть определенные сценарии, где следует использовать параллельные потоки. В этом сценарии параллельные потоки не дадут лучшей производительности. и да, параллельные потоки могут не дать желаемых результатов в некоторых случаях. List<String> deDupStringList3 = stringList.stream().map(String::toLowerCase).distinct().collect(Collectors.toList());
должно быть подходящее решение в этом случае
Если вы не хотите дубликатов, используйте Set вместо a List
. Для преобразования List
в a Set
вы можете использовать следующий код:
// list is some List of Strings
Set<String> s = new HashSet<String>(list);
Если действительно необходимо, вы можете использовать ту же конструкцию, чтобы преобразовать Set
обратно в List
.
Set
не может быть использовано здесь.
Вы также можете сделать это таким образом и сохранить порядок:
// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
Потоки Java 8 предоставляют очень простой способ удаления дублирующихся элементов из списка. Используя отличный метод. Если у нас есть список городов, и мы хотим удалить дубликаты из этого списка, это можно сделать в одну строку -
List<String> cityList = new ArrayList<>();
cityList.add("Delhi");
cityList.add("Mumbai");
cityList.add("Bangalore");
cityList.add("Chennai");
cityList.add("Kolkata");
cityList.add("Mumbai");
cityList = cityList.stream().distinct().collect(Collectors.toList());
Вот способ, который не влияет на порядок составления списка:
ArrayList l1 = new ArrayList();
ArrayList l2 = new ArrayList();
Iterator iterator = l1.iterator();
while (iterator.hasNext()) {
YourClass o = (YourClass) iterator.next();
if(!l2.contains(o)) l2.add(o);
}
l1 - исходный список, а l2 - список без повторяющихся элементов (убедитесь, что у YourClass есть метод equals в соответствии с тем, что вы хотите отстаивать для равенства)
ArrayList<T>
следует использовать вместо ArrayList
) 2) явного создания итератора можно избежать с помощью a for (T current : l1) { ... }
. Даже если вы хотели использовать Iterator
явно, с iterador
ошибкой.
Можно удалить дубликаты из массива без использования HashSet или еще одного массива .
Попробуйте этот код ..
ArrayList<String> lst = new ArrayList<String>();
lst.add("ABC");
lst.add("ABC");
lst.add("ABCD");
lst.add("ABCD");
lst.add("ABCE");
System.out.println("Duplicates List "+lst);
Object[] st = lst.toArray();
for (Object s : st) {
if (lst.indexOf(s) != lst.lastIndexOf(s)) {
lst.remove(lst.lastIndexOf(s));
}
}
System.out.println("Distinct List "+lst);
Выход
Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]
ImmutableSet.copyOf(lst).toList()
.
indexOf
повторяет lst
использование цикла for.
Также есть вариант ImmutableSet
из Гуавы ( вот документация):
ImmutableSet.copyOf(list);
ImmutableSet.asList()
метод, возвращающий ImmutableList
, если вам нужно вернуть его как List
.
это может решить проблему:
private List<SomeClass> clearListFromDuplicateFirstName(List<SomeClass> list1) {
Map<String, SomeClass> cleanMap = new LinkedHashMap<String, SomeClass>();
for (int i = 0; i < list1.size(); i++) {
cleanMap.put(list1.get(i).getFirstName(), list1.get(i));
}
List<SomeClass> list = new ArrayList<SomeClass>(cleanMap.values());
return list;
}
Возможно, это немного излишне, но мне нравится такая изолированная проблема. :)
Этот код использует временный набор (для проверки уникальности), но удаляет элементы непосредственно внутри исходного списка. Так как удаление элемента внутри ArrayList может вызвать огромное количество копирования массива, метод удаления (int) избегается.
public static <T> void removeDuplicates(ArrayList<T> list) {
int size = list.size();
int out = 0;
{
final Set<T> encountered = new HashSet<T>();
for (int in = 0; in < size; in++) {
final T t = list.get(in);
final boolean first = encountered.add(t);
if (first) {
list.set(out++, t);
}
}
}
while (out < size) {
list.remove(--size);
}
}
Пока мы на этом, вот версия для LinkedList (намного лучше!):
public static <T> void removeDuplicates(LinkedList<T> list) {
final Set<T> encountered = new HashSet<T>();
for (Iterator<T> iter = list.iterator(); iter.hasNext(); ) {
final T t = iter.next();
final boolean first = encountered.add(t);
if (!first) {
iter.remove();
}
}
}
Используйте интерфейс маркера, чтобы представить унифицированное решение для List:
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
РЕДАКТИРОВАТЬ: Я думаю, что дженерики действительно не добавляет никакой ценности здесь ... Ну, хорошо. :)
public static void main(String[] args){
ArrayList<Object> al = new ArrayList<Object>();
al.add("abc");
al.add('a');
al.add('b');
al.add('a');
al.add("abc");
al.add(10.3);
al.add('c');
al.add(10);
al.add("abc");
al.add(10);
System.out.println("Before Duplicate Remove:"+al);
for(int i=0;i<al.size();i++){
for(int j=i+1;j<al.size();j++){
if(al.get(i).equals(al.get(j))){
al.remove(j);
j--;
}
}
}
System.out.println("After Removing duplicate:"+al);
}
Если вы желаете использовать стороннюю библиотеку, вы можете использовать метод distinct()
в Eclipse Collections (ранее GS Collections).
ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
FastList.newListWith(1, 3, 2),
integers.distinct());
Преимущество использования distinct()
вместо преобразования в набор, а затем обратно в список состоит в том, что distinct()
сохраняется порядок исходного списка, сохраняя первое вхождение каждого элемента. Это реализовано с использованием как Set, так и List.
MutableSet<T> seenSoFar = UnifiedSet.newSet();
int size = list.size();
for (int i = 0; i < size; i++)
{
T item = list.get(i);
if (seenSoFar.add(item))
{
targetCollection.add(item);
}
}
return targetCollection;
Если вы не можете преобразовать свой исходный список в тип коллекций Eclipse, вы можете использовать ListAdapter для получения того же API.
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
Примечание: я являюсь коммиттером для Eclipse Collections.
Эти три строки кода могут удалить дублированный элемент из ArrayList или любой коллекции.
List<Entity> entities = repository.findByUserId(userId);
Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
Когда вы заполняете ArrayList, используйте условие для каждого элемента. Например:
ArrayList< Integer > al = new ArrayList< Integer >();
// fill 1
for ( int i = 0; i <= 5; i++ )
if ( !al.contains( i ) )
al.add( i );
// fill 2
for (int i = 0; i <= 10; i++ )
if ( !al.contains( i ) )
al.add( i );
for( Integer i: al )
{
System.out.print( i + " ");
}
Мы получим массив {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Если вы хотите сохранить свой заказ, то лучше всего использовать LinkedHashSet . Потому что, если вы хотите передать этот список в запрос на вставку путем его итерации, порядок будет сохранен.
Попробуй это
LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);
Это преобразование будет очень полезно, когда вы хотите вернуть список, но не набор.
Код:
List<String> duplicatList = new ArrayList<String>();
duplicatList = Arrays.asList("AA","BB","CC","DD","DD","EE","AA","FF");
//above AA and DD are duplicate
Set<String> uniqueList = new HashSet<String>(duplicatList);
duplicatList = new ArrayList<String>(uniqueList); //let GC will doing free memory
System.out.println("Removed Duplicate : "+duplicatList);
Примечание: определенно, будут накладные расходы памяти.
ArrayList<String> city=new ArrayList<String>();
city.add("rajkot");
city.add("gondal");
city.add("rajkot");
city.add("gova");
city.add("baroda");
city.add("morbi");
city.add("gova");
HashSet<String> hashSet = new HashSet<String>();
hashSet.addAll(city);
city.clear();
city.addAll(hashSet);
Toast.makeText(getActivity(),"" + city.toString(),Toast.LENGTH_SHORT).show();
LinkedHashSet сделает свое дело.
String[] arr2 = {"5","1","2","3","3","4","1","2"};
Set<String> set = new LinkedHashSet<String>(Arrays.asList(arr2));
for(String s1 : set)
System.out.println(s1);
System.out.println( "------------------------" );
String[] arr3 = set.toArray(new String[0]);
for(int i = 0; i < arr3.length; i++)
System.out.println(arr3[i].toString());
// вывод: 5,1,2,3,4
List<String> result = new ArrayList<String>();
Set<String> set = new LinkedHashSet<String>();
String s = "ravi is a good!boy. But ravi is very nasty fellow.";
StringTokenizer st = new StringTokenizer(s, " ,. ,!");
while (st.hasMoreTokens()) {
result.add(st.nextToken());
}
System.out.println(result);
set.addAll(result);
result.clear();
result.addAll(set);
System.out.println(result);
output:
[ravi, is, a, good, boy, But, ravi, is, very, nasty, fellow]
[ravi, is, a, good, boy, But, very, nasty, fellow]
Это используется для вашего списка пользовательских объектов
public List<Contact> removeDuplicates(List<Contact> list) {
// Set set1 = new LinkedHashSet(list);
Set set = new TreeSet(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (((Contact) o1).getId().equalsIgnoreCase(((Contact) o2).getId()) /*&&
((Contact)o1).getName().equalsIgnoreCase(((Contact)o2).getName())*/) {
return 0;
}
return 1;
}
});
set.addAll(list);
final List newList = new ArrayList(set);
return newList;
}
Вы можете использовать вложенный цикл в следующем:
ArrayList<Class1> l1 = new ArrayList<Class1>();
ArrayList<Class1> l2 = new ArrayList<Class1>();
Iterator iterator1 = l1.iterator();
boolean repeated = false;
while (iterator1.hasNext())
{
Class1 c1 = (Class1) iterator1.next();
for (Class1 _c: l2) {
if(_c.getId() == c1.getId())
repeated = true;
}
if(!repeated)
l2.add(c1);
}
Вот мой код без использования какой-либо другой структуры данных, такой как set или hashmap
for (int i = 0; i < Models.size(); i++){
for (int j = i + 1; j < Models.size(); j++) {
if (Models.get(i).getName().equals(Models.get(j).getName())) {
Models.remove(j);
j--;
}
}
}
import java.util.*;
class RemoveDupFrmString
{
public static void main(String[] args)
{
String s="appsc";
Set<Character> unique = new LinkedHashSet<Character> ();
for(char c : s.toCharArray()) {
System.out.println(unique.add(c));
}
for(char dis:unique){
System.out.println(dis);
}
}
}
ArrayList<String> list = new ArrayList<String>();
HashSet<String> unique = new LinkedHashSet<String>();
HashSet<String> dup = new LinkedHashSet<String>();
boolean b = false;
list.add("Hello");
list.add("Hello");
list.add("how");
list.add("are");
list.add("u");
list.add("u");
for(Iterator iterator= list.iterator();iterator.hasNext();)
{
String value = (String)iterator.next();
System.out.println(value);
if(b==unique.add(value))
dup.add(value);
else
unique.add(value);
}
System.out.println(unique);
System.out.println(dup);
Если вы хотите удалить дубликаты из ArrayList, найдите приведенную ниже логику,
public static Object[] removeDuplicate(Object[] inputArray)
{
long startTime = System.nanoTime();
int totalSize = inputArray.length;
Object[] resultArray = new Object[totalSize];
int newSize = 0;
for(int i=0; i<totalSize; i++)
{
Object value = inputArray[i];
if(value == null)
{
continue;
}
for(int j=i+1; j<totalSize; j++)
{
if(value.equals(inputArray[j]))
{
inputArray[j] = null;
}
}
resultArray[newSize++] = value;
}
long endTime = System.nanoTime()-startTime;
System.out.println("Total Time-B:"+endTime);
return resultArray;
}