Saya punya ArrayList<String>
, dan saya ingin menghapus string berulang dari itu. Bagaimana saya bisa melakukan ini?
Saya punya ArrayList<String>
, dan saya ingin menghapus string berulang dari itu. Bagaimana saya bisa melakukan ini?
Jawaban:
Jika Anda tidak ingin duplikat dalam Collection
, Anda harus mempertimbangkan mengapa Anda menggunakan Collection
yang memungkinkan duplikat. Cara termudah untuk menghapus elemen berulang adalah dengan menambahkan konten ke Set
(yang tidak akan memungkinkan duplikat) dan kemudian menambahkan Set
kembali ke ArrayList
:
Set<String> set = new HashSet<>(yourList);
yourList.clear();
yourList.addAll(set);
Tentu saja, ini menghancurkan urutan elemen dalam 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
dan Set
(bukan tipe implementasi ArrayList
dan HashSet
seperti dalam contoh Anda).
new HashSet(al)
alih-alih menginisialisasi untuk mengosongkan dan memanggil addAll
.
Object
memiliki beberapa nilai jika dua dari mereka mengulang saya menganggapnya sebagai duplikat (nilai-nilai lain dapat berbeda) dan digunakan Set
?
Meskipun mengonversikan ArrayList
ke yang HashSet
efektif menghapus duplikat, jika Anda perlu mempertahankan urutan penyisipan, saya lebih suka menyarankan Anda untuk menggunakan varian ini
// list is some List of Strings
Set<String> s = new LinkedHashSet<>(list);
Kemudian, jika Anda perlu mendapatkan kembali List
referensi, Anda dapat menggunakan lagi konstruktor konversi.
Di Jawa 8:
List<String> deduped = list.stream().distinct().collect(Collectors.toList());
Harap perhatikan bahwa kontrak hashCode-equals untuk anggota daftar harus dihormati agar penyaringan berfungsi dengan baik.
addAll
untuk new TreeSet<String>(String.CASE_INSENSITIVE_ORDER)
. Elemen pertama yang ditambahkan akan tetap di set jadi jika daftar Anda berisi "Dog" dan "dog" (dalam urutan itu) TreeSet
akan berisi "Dog". Jika pesanan harus dipertahankan maka sebelum baris dalam jawaban dimasukkan list.replaceAll(String::toUpperCase);
.
Misalkan kita memiliki daftar String
seperti:
List<String> strList = new ArrayList<>(5);
// insert up to five items to list.
Kemudian kita dapat menghapus elemen duplikat dengan berbagai cara.
List<String> deDupStringList = new ArrayList<>(new HashSet<>(strList));
Catatan: Jika kita ingin menjaga ketertiban penyisipan maka kita perlu untuk menggunakan LinkedHashSet
di tempatHashSet
List<String> deDupStringList2 = Lists.newArrayList(Sets.newHashSet(strList));
List<String> deDupStringList3 = strList.stream().distinct().collect(Collectors.toList());
Catatan: Jika kami ingin mengumpulkan hasilnya dalam implementasi daftar tertentu misalnyaLinkedList
maka kami dapat mengubah contoh di atas sebagai:
List<String> deDupStringList3 = strList.stream().distinct()
.collect(Collectors.toCollection(LinkedList::new));
Kita dapat menggunakan parallelStream
juga dalam kode di atas tetapi mungkin tidak memberikan manfaat kinerja yang diharapkan. Lihat pertanyaan ini untuk lebih lanjut.
parallel streams
akan selalu memberikan kinerja yang lebih baik. Tapi itu hanya mitos. Saya kemudian mengetahui bahwa ada beberapa skenario di mana aliran paralel harus digunakan. Dalam skenario ini, aliran paralel tidak akan memberikan kinerja yang lebih baik. dan ya aliran paralel mungkin tidak memberikan hasil yang diinginkan beberapa kasus. List<String> deDupStringList3 = stringList.stream().map(String::toLowerCase).distinct().collect(Collectors.toList());
harus menjadi solusi yang cocok dalam kasus ini
Jika Anda tidak ingin duplikat, gunakan Set daripada a List
. Untuk mengonversi a List
menjadi Set
Anda dapat menggunakan kode berikut:
// list is some List of Strings
Set<String> s = new HashSet<String>(list);
Jika benar - benar diperlukan, Anda dapat menggunakan konstruksi yang sama untuk mengubah Set
kembali menjadi a List
.
Set
tidak bisa digunakan di sini.
Anda juga dapat melakukannya dengan cara ini, dan menjaga ketertiban:
// delete duplicates (if any) from 'myArrayList'
myArrayList = new ArrayList<String>(new LinkedHashSet<String>(myArrayList));
Java 8 stream menyediakan cara yang sangat sederhana untuk menghapus elemen duplikat dari daftar. Menggunakan metode yang berbeda. Jika kami memiliki daftar kota dan kami ingin menghapus duplikat dari daftar itu dapat dilakukan dalam satu baris -
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());
Berikut cara yang tidak memengaruhi pemesanan daftar Anda:
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 adalah daftar asli, dan l2 adalah daftar tanpa item berulang (Pastikan YourClass memiliki metode yang sama dengan apa yang ingin Anda perjuangkan untuk kesetaraan)
ArrayList<T>
harus digunakan sebagai ganti ArrayList
) 2) Pembuatan iterator eksplisit dapat dihindari dengan menggunakan a for (T current : l1) { ... }
. Bahkan jika Anda ingin menggunakan secara Iterator
eksplisit, iterador
salah eja.
Dimungkinkan untuk menghapus duplikat dari arraylist tanpa menggunakan HashSet atau satu arraylist lagi .
Coba kode ini ..
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);
Output adalah
Duplicates List [ABC, ABC, ABCD, ABCD, ABCE]
Distinct List [ABC, ABCD, ABCE]
ImmutableSet.copyOf(lst).toList()
.
indexOf
iterasi lst
menggunakan for for loop.
Ada juga ImmutableSet
dari Guava sebagai opsi (di sini adalah dokumentasi):
ImmutableSet.copyOf(list);
ImmutableSet.asList()
metode, mengembalikan ImmutableList
, jika Anda memerlukannya kembali sebagai List
.
ini bisa menyelesaikan masalah:
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;
}
Mungkin agak berlebihan, tetapi saya menikmati masalah terisolasi semacam ini. :)
Kode ini menggunakan Set sementara (untuk pemeriksaan keunikan) tetapi menghapus elemen langsung di dalam daftar asli. Karena penghapusan elemen di dalam ArrayList dapat menyebabkan sejumlah besar penyalinan array, metode penghapusan (int) dihindari.
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);
}
}
Sementara kami melakukannya, ini adalah versi untuk LinkedList (jauh lebih bagus!):
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();
}
}
}
Gunakan antarmuka penanda untuk menyajikan solusi terpadu untuk Daftar:
public static <T> void removeDuplicates(List<T> list) {
if (list instanceof RandomAccess) {
// use first version here
} else {
// use other version here
}
}
EDIT: Saya kira barang generik tidak benar-benar menambah nilai apa pun di sini .. :)
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);
}
Jika Anda ingin menggunakan perpustakaan pihak ketiga, Anda dapat menggunakan metode ini distinct()
di Eclipse Collections (sebelumnya GS Collections).
ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
FastList.newListWith(1, 3, 2),
integers.distinct());
Keuntungan menggunakan distinct()
alih-alih mengonversi ke Set dan kemudian kembali ke Daftar adalah distinct()
mempertahankan urutan Daftar asli, mempertahankan kemunculan pertama setiap elemen. Diimplementasikan dengan menggunakan Set dan Daftar.
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;
Jika Anda tidak dapat mengonversi Daftar asli Anda menjadi jenis Koleksi Eclipse, Anda bisa menggunakan ListAdapter untuk mendapatkan API yang sama.
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
Catatan: Saya pengendara untuk Eclipse Collections.
Tiga baris kode ini dapat menghapus elemen yang digandakan dari ArrayList atau koleksi apa pun.
List<Entity> entities = repository.findByUserId(userId);
Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
Saat Anda mengisi ArrayList, gunakan kondisi untuk setiap elemen. Sebagai contoh:
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 + " ");
}
Kami akan mendapatkan array {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
Jika Anda ingin mempertahankan Pesanan Anda, maka yang terbaik adalah menggunakan LinkedHashSet . Karena jika Anda ingin meneruskan Daftar ini ke Query Sisipkan dengan menghapusnya, urutannya akan dipertahankan.
Coba ini
LinkedHashSet link=new LinkedHashSet();
List listOfValues=new ArrayList();
listOfValues.add(link);
Konversi ini akan sangat membantu ketika Anda ingin mengembalikan Daftar tetapi bukan Set.
Kode:
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);
Catatan: Pasti, akan ada overhead memori.
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 akan melakukan triknya.
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());
// output: 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]
Ini digunakan untuk daftar Objek Kustom Anda
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;
}
Anda dapat menggunakan nested loop di follow:
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);
}
Seperti yang dikatakan sebelumnya, Anda harus menggunakan kelas yang mengimplementasikan antarmuka Set bukannya Daftar untuk memastikan keaslian elemen. Jika Anda harus menjaga urutan elemen, antarmuka SortedSet kemudian dapat digunakan; kelas TreeSet mengimplementasikan antarmuka itu.
Ini kode saya tanpa menggunakan struktur data lain seperti set atau 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);
Jika Anda ingin menghapus duplikat dari ArrayList berarti temukan logika di bawah ini,
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;
}