답변:
에서 중복을 원하지 않으면 중복 을 허용하는를 Collection
사용하는 이유를 고려해야합니다 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
A를가 HashSet
효과적으로 중복 제거 당신이 삽입 순서를 유지해야하는 경우, 차라리이 변형을 사용하는 것이 좋을 것
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
그런 다음 List
참조를 다시 가져와야하는 경우 변환 생성자를 다시 사용할 수 있습니다.
자바 8 :
List<String> deduped = list.stream().distinct().collect(Collectors.toList());
있습니다 해시 코드가-동일 리스트 회원을위한 계약은 제대로 작동하려면 필터링 존중해야한다.
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());
이 경우에 적합한 솔루션이어야합니다
중복을 원하지 않으면 a 대신 Set을 사용 하십시오List
. 를 a List
로 변환하려면 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는 반복되는 항목이없는 목록입니다 (YouClass에 평등을 유지하려는 항목에 따라 equals 메소드가 있는지 확인하십시오)
ArrayList<T>
대신에 사용해야 함 ArrayList
) 2)을 사용하여 명시 적 반복자 생성을 피할 수 있습니다 for (T current : l1) { ... }
. Iterator
명시 적으로 사용하고 싶더라도 iterador
철자가 잘못되었습니다.
HashSet 또는 하나 이상의 arraylist를 사용하지 않고 arraylist에서 중복을 제거 할 수 있습니다 .
이 코드를 사용해보십시오.
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
.
도 있습니다 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 내에서 요소를 제거하면 많은 양의 배열 복사가 발생할 수 있으므로 remove (int) -method가 방지됩니다.
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
}
}
편집 : generics-stuff는 실제로 여기에 어떤 가치도 추가하지 않는다고 생각합니다. 오. :)
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);
}
써드 파티 라이브러리를 사용하려는 경우 Eclipse Collections (이전 GS Collections) 의 메소드 distinct()
를 사용할 수 있습니다 .
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;
원래 List를 Eclipse Collections 유형으로 변환 할 수없는 경우 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}을 얻게됩니다
암호:
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--;
}
}
}
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;
}