উত্তর:
আপনি যদি একটিতে সদৃশ চান না 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
একটি থেকে 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)
। যুক্ত হওয়া প্রথম উপাদানটি সেটে থাকবে তাই আপনার তালিকায় যদি "কুকুর" এবং "কুকুর" থাকে (সেই ক্রমে) TreeSet
এতে "কুকুর" থাকবে। যদি অর্ডার অবশ্যই সংরক্ষণ করতে হয় তবে উত্তরটিতে রেখার আগে 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());
এক্ষেত্রে উপযুক্ত সমাধান হওয়া উচিত
আপনি যদি সদৃশ চান না, একটি এর পরিবর্তে একটি সেট ব্যবহার করুনList
। একটি রূপান্তর করতে 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));
জাভা 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 পুনরাবৃত্তি আইটেম ছাড়া তালিকা (নিশ্চিত করুন যে আপনার ক্লাস আপনি সমতার পক্ষে দাঁড়াতে চান তার অনুসারে সমান পদ্ধতি রয়েছে)
ArrayList<T>
পরিবর্তে ব্যবহার করা উচিত ArrayList
) 2) স্পষ্টত পুনরাবৃত্তি তৈরির মাধ্যমে এটিকে এড়ানো যায় for (T current : l1) { ... }
। এমনকি যদি আপনি একটি Iterator
স্পষ্টভাবে ব্যবহার করতে চান iterador
তবে ভুল বানান।
এটা তোলে ব্যবহার না করেই arraylist থেকে সদৃশ অপসারণ করা সম্ভব HashSet বা আরও একটি 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;
}
সম্ভবত কিছুটা ওভারকিল, তবে আমি এই ধরণের বিচ্ছিন্ন সমস্যাটি উপভোগ করি। :)
এই কোডটিতে অস্থায়ী সেট (স্বতন্ত্রতা পরীক্ষার জন্য) ব্যবহার করা হয়েছে তবে মূল তালিকার অভ্যন্তরে উপাদানগুলি সরানো হয়েছে। যেহেতু একটি অ্যারেলিস্টের ভিতরে উপাদান অপসারণ বিপুল পরিমাণ অ্যারে অনুলিপি প্ররোচিত করতে পারে, তাই অপসারণ (অন্তর্নিহিত) -মথাদৃত এড়ানো হয়।
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);
}
}
আমরা যখন এটির সাথে রয়েছি, এখানে লিঙ্কডলিস্টের জন্য একটি সংস্করণ রয়েছে (অনেক সুন্দর!):
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();
}
}
}
তালিকার জন্য একীভূত সমাধান উপস্থাপন করতে মার্কার ইন্টারফেসটি ব্যবহার করুন:
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 সংগ্রহগুলিতে (পূর্বে জিএস সংগ্রহ) পদ্ধতিটি ব্যবহার করতে পারেন ।
ListIterable<Integer> integers = FastList.newListWith(1, 3, 1, 2, 2, 1);
Assert.assertEquals(
FastList.newListWith(1, 3, 2),
integers.distinct());
distinct()
কোনও সেটে রূপান্তরিত না করে এবং তারপরে একটি তালিকায় ফিরে যাওয়ার পরিবর্তে ব্যবহারের সুবিধাটি হ'ল distinct()
প্রতিটি তালিকার প্রথম উপস্থিতি ধরে রেখে মূল তালিকার ক্রম সংরক্ষণ করে। এটি সেট এবং একটি তালিকা উভয় ব্যবহার করে প্রয়োগ করা হয়েছে।
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;
আপনি যদি নিজের আসল তালিকাটিকে একটি Elpipse সংগ্রহের ধরণে রূপান্তর করতে না পারেন তবে একই API পেতে আপনি তালিকাগুলি ব্যবহার করতে পারেন।
MutableList<Integer> distinct = ListAdapter.adapt(integers).distinct();
দ্রষ্টব্য: আমি গ্রহগ্রাহ সংগ্রহের প্রতিশ্রুতিবদ্ধ।
এই তিনটি লাইনের কোড অ্যারেলিস্ট বা কোনও সংগ্রহ থেকে সদৃশ উপাদানটিকে সরিয়ে ফেলতে পারে।
List<Entity> entities = repository.findByUserId(userId);
Set<Entity> s = new LinkedHashSet<Entity>(entities);
entities.clear();
entities.addAll(s);
আপনি যখন অ্যারেলিস্টটি পূরণ করছেন, প্রতিটি উপাদানগুলির জন্য একটি শর্ত ব্যবহার করুন। উদাহরণ স্বরূপ:
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 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();
লিংকডহ্যাশসেটটি কৌশলটি করবে।
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);
}
সেট বা হ্যাশম্যাপের মতো অন্য কোনও ডেটা স্ট্রাকচার ব্যবহার না করেই এখানে আমার কোড
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);
আপনি যদি অ্যারেলিস্ট থেকে সদৃশগুলি অপসারণ করতে চান তবে নীচের যুক্তিটি সন্ধান করুন,
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;
}