অবজেক্টের নাম ক্ষেত্রটি ব্যবহার করে একটি তালিকা <অবজেক্ট> বর্ণানুক্রমিকভাবে কীভাবে সাজানো যায়


102

আমি একটি বস্তুর তালিকা আছে মত List<Object> p.আমি বর্ণানুক্রমে এই তালিকায় সাজাতে অবজেক্ট নামের ক্ষেত্রটি ব্যবহার চাই। অবজেক্টে 10 টি ক্ষেত্র রয়েছে এবং নাম ক্ষেত্রগুলির মধ্যে একটি।

if (list.size() > 0) {
    Collections.sort(list, new Comparator<Campaign>() {
        @Override
        public int compare(final Object object1, final Object object2) {
        return String.compare(object1.getName(), object2.getName());
        }
    } );
}

তবে স্ট্রিং.কম.পায়ারের মতো কিছুই নেই ..?


3
কীভাবে নাম পাচ্ছেন? - Objectএর নাম নেই আপনি ব্যবহার মানে .toString()?
ম্যাট ফেনউইক

object1এবং object2টাইপ করা প্রয়োজন Campaign, এবং তুলনা ফাংশন object1.getName().compareTo(object2.getName())
বার্ট ভ্যান হিউকেলোম

আপনি মিশ্রিত List<Object>এবং Comparator<Campaign>। আপনি এটা করতে পারবেন না। উভয় ক্ষেত্রেই আপনি List<Object>এবং Comparator<Object>বা List<Campaign>এবংComparator<Campaign>
ভিক্টর

উত্তর:


230

আপনার কোড থেকে দেখে মনে হচ্ছে আপনার Comparatorইতিমধ্যে পরামিতি হয়েছে Campaign। এটি শুধুমাত্র সাথে কাজ করবে List<Campaign>। এছাড়াও, আপনি যে পদ্ধতিটি সন্ধান করছেন তা হ'ল compareTo

if (list.size() > 0) {
  Collections.sort(list, new Comparator<Campaign>() {
      @Override
      public int compare(final Campaign object1, final Campaign object2) {
          return object1.getName().compareTo(object2.getName());
      }
  });
}

বা আপনি যদি জাভা ব্যবহার করছেন 1.8

list
  .stream()
  .sorted((object1, object2) -> object1.getName().compareTo(object2.getName()));

একটি চূড়ান্ত মন্তব্য - তালিকার আকার চেক করার কোনও মানে নেই। বাছাই করা খালি তালিকায় কাজ করবে।


2
আমি মনে করি এটিই সেরা উত্তর যা ওপি যা খুঁজছে তাতে সবকিছু বিচ্ছিন্ন করে দেয়। এবং মন্তব্যগুলি থেকে, আমি মনে করি তিনি কেস-সংবেদনশীল চান, তাই কেবল তুলনামূলকভাবে তুলনা করার জন্য পরিবর্তন করুন TOIgnoreCase
গ্রেগ কেস

নাবালিকা প্রথম সমাধানে উন্নতি করে: আমরা যদি (list.size ()> 1) করতে পারি - 1 আইটেম হিসাবে বাছাই করার দরকার নেই ..
রামি ইয়াম্পলস্কি

12
আপনি ব্যবহার করতে পারেনComparator.comparing(Campaign::getName)
জোস দা সিলভা

4
list.sort((object1, object2) -> object1. getName().compareTo(object2. getName()));আমার জন্য কাজ করেছেন
লুকাস

1
sortedList = list.stream().sort((object1, object2) -> object1. getName().compareTo(object2. getName()))..collect(Collectors.toList());একটি নতুন বাছাই করা তালিকা পেতে ব্যবহার করার চেষ্টা করুন
লুকাশ

16

বর্ণানুক্রমিকভাবে স্ট্রিংয়ের সর্বাধিক সঠিক উপায় হ'ল Collatorআন্তর্জাতিকীকরণের কারণে use কয়েকটি অতিরিক্ত অক্ষর ইত্যাদির কারণে কিছু ভাষার আলাদা ক্রম থাকে etc.

   Collator collator = Collator.getInstance(Locale.US);
   if (!list.isEmpty()) {
    Collections.sort(list, new Comparator<Campaign>() {
        @Override
        public int compare(Campaign c1, Campaign c2) {
            //You should ensure that list doesn't contain null values!
            return collator.compare(c1.getName(), c2.getName());
        }
       });
   }

আপনি যদি আন্তর্জাতিকীকরণের বিষয়ে চিন্তা না করেন string.compare(otherString)

   if (!list.isEmpty()) {
    Collections.sort(list, new Comparator<Campaign>() {
        @Override
        public int compare(Campaign c1, Campaign c2) {
            //You should ensure that list doesn't contain null values!
            return c1.getName().compare(c2.getName());
        }
       });
   }

11

ইন্টারফেস Collections.sort()এবং একবার দেখুন Comparator

স্ট্রিং তুলনাটি object1.getName().compareTo(object2.getName())বা object2.getName().compareTo(object1.getName())(আপনার পছন্দ অনুসারে বাছাইয়ের দিকের উপর নির্ভর করে) করা যেতে পারে।

যদি আপনি চান বাছাইটি কেস অ্যাজোনস্টিক হোক, তাই করুন object1.getName().toUpperCase().compareTo(object2.getName().toUpperCase())


এবং আপনি কীভাবে সেই ক্ষেত্রটি টাইপ namaথেকে আহরণের পরামর্শ দিচ্ছেন Object? এই উত্তরটি সম্পূর্ণ নয়।
amit

নাম নিষ্কাশন বস্তুর ধরণের উপর নির্ভর করে। আমার ধারণা, এটি কেবল একটি স্থানধারক প্রকার। আপনি যদি আরও কংক্রিটের ধরণ দিতে না পারেন তবে আপনি প্রতিবিম্বটি ব্যবহার করে শেষ করতে পারেন।
tobiasbayer


7
public class ObjectComparator implements Comparator<Object> {

    public int compare(Object obj1, Object obj2) {
        return obj1.getName().compareTo(obj2.getName());
    }

}

দয়া করে আপনার শ্রেণীর সাথে অবজেক্টটি প্রতিস্থাপন করুন যাতে নাম ক্ষেত্র রয়েছে

ব্যবহার:

ObjectComparator comparator = new ObjectComparator();
Collections.sort(list, comparator);

আমি এটি করেছি তবে "অনুসন্ধান" করার আগে "অনুসন্ধান" আসছে না: ((
সৌরভ কুমার

আপনি যদি obj1.getName().compareTo(obj2.getName()obj2.getName().compareTo(obj1.getName()
ওঁদের

2

কিছুটা এইরকম

  List<FancyObject> theList =  ;
  Collections.sort (theList,
                    new Comparator<FancyObject> ()
                    { int compare (final FancyObject a, final FancyObject d)
                          { return (a.getName().compareTo(d.getName())); }});

2

এখানে রবার্ট বি এর উত্তরের একটি সংস্করণ List<T>যা প্রতিচ্ছবি এবং কোনও তৃতীয় পক্ষের লাইব্রেরি ব্যবহার করে অবজেক্টের একটি নির্দিষ্ট স্ট্রিং সম্পত্তির জন্য বাছাই করে কাজ করে works

/**
 * Sorts a List by the specified String property name of the object.
 * 
 * @param list
 * @param propertyName
 */
public static <T> void sortList(List<T> list, final String propertyName) {

    if (list.size() > 0) {
        Collections.sort(list, new Comparator<T>() {
            @Override
            public int compare(final T object1, final T object2) {
                String property1 = (String)ReflectionUtils.getSpecifiedFieldValue (propertyName, object1);
                String property2 = (String)ReflectionUtils.getSpecifiedFieldValue (propertyName, object2);
                return property1.compareToIgnoreCase (property2);
            }
        });
    }
}


public static Object getSpecifiedFieldValue (String property, Object obj) {

    Object result = null;

    try {
        Class<?> objectClass = obj.getClass();
        Field objectField = getDeclaredField(property, objectClass);
        if (objectField!=null) {
            objectField.setAccessible(true);
            result = objectField.get(obj);
        }
    } catch (Exception e) {         
    }
    return result;
}

public static Field getDeclaredField(String fieldName, Class<?> type) {

    Field result = null;
    try {
        result = type.getDeclaredField(fieldName);
    } catch (Exception e) {
    }       

    if (result == null) {
        Class<?> superclass = type.getSuperclass();     
        if (superclass != null && !superclass.getName().equals("java.lang.Object")) {       
            return getDeclaredField(fieldName, type.getSuperclass());
        }
    }
    return result;
}

2

আপনি Eclipse সংগ্রহsortThisBy() থেকে ব্যবহার করতে পারেন :

MutableList<Campaign> list = Lists.mutable.empty();
list.sortThisBy(Campaign::getName);

আপনি যদি তালিকার ধরণটি পরিবর্তন করতে না পারেন তবে List:

List<Campaign> list = new ArrayList<>();
ListAdapter.adapt(list).sortThisBy(Campaign::getName);

দ্রষ্টব্য: আমি গ্রহন গ্রাহক সংগ্রহের একজন সহযোগী।



1

যদি আপনার অবজেক্টগুলির কিছু সাধারণ পূর্বপুরুষ থাকে [তবে এটি হতে দিন T] এর List<T>পরিবর্তে আপনার নাম ব্যবহার করে এই টিটির জন্য তুলনামূলকList<Object> প্রয়োগ করা উচিত ।

আপনার যদি কোনও সাধারণ পূর্বপুরুষ না থাকে তবে আপনি কোনও প্রতিযোগী বাস্তবায়ন করতে পারেন এবং নামটি বের করতে প্রতিবিম্বটি ব্যবহার করতে পারেন , দ্রষ্টব্য যে এটি অনিরাপদ, অসন্তুষ্ট এবং প্রতিবিম্বটি ব্যবহার করতে খারাপ পারফরম্যান্সে ভুগছে তবে এটি আপনাকে ক্ষেত্রের নাম অ্যাক্সেস করতে দেয় বস্তুর প্রকৃত ধরণ সম্পর্কে কিছু না জেনেও [প্রাসঙ্গিক নামের সাথে এটির ক্ষেত্র রয়েছে]

উভয় ক্ষেত্রেই, আপনার বাছাই করার জন্য সংগ্রহে.সোর্ট () ব্যবহার করা উচিত ।



0

এটি YourClassপরিবর্তে একটি তালিকা ধরে নিচ্ছেObject , যেমন অ্যামিত দ্বারা ব্যাখ্যা করা হয়েছে ।

গুগল পেয়ারা লাইব্রেরি থেকে আপনি এই বিটটি ব্যবহার করতে পারেন:

Collections.sort(list, Ordering.natural()
  .onResultOf(new Function<String,YourClass>() {
  public String call(YourClass o) {
     return o.getName();
  }))
  .nullsLast();

অন্যান্য উত্তর যা উল্লেখ Comparatorসাল থেকে ভুল নয় Orderingকার্যকরী Comparator। এই সমাধানটি আমার মতে কিছুটা সহজ, যদিও আপনি যদি শিক্ষানবিশ হন এবং লাইব্রেরি এবং / অথবা "ফাংশনাল প্রোগ্রামিং" ব্যবহার করতে অভ্যস্ত না হন তবে এটি আরও কঠিন হতে পারে।

আমার নিজের প্রশ্নের এই উত্তরটি নির্লজ্জভাবে অনুলিপি করেছেন


এটি আমি এইভাবেই করতাম তবে ওপি'র পক্ষে এটি খুব বেশি হতে পারে।
গ্রেগ কেস

0

একটি নির্বাচন বাছাই ব্যবহার

for(int i = list.size() - 1; i > 0; i--){

  int max = i

  for(int j = 0; j < i; j++){
      if(list.get(j).getName().compareTo(list.get(j).getName()) > 0){
            max= j;
      }
  }

  //make the swap
  Object temp = list.get(i);
  list.get(i) = list.get(max);
  list.get(max) = temp;

}

(1) কেন তিনি চাকাটি পুনরায় উদ্ভাবন করবেন? এর সাথে কি হয়েছে Collections.sort()? (২) তালিকাটি টাইপযুক্ত List<Object>, এবং তাই list.get(j).getName()সংকলন করবে না। (3) এই দ্রবণটি হ'ল (এন ^ 2), তবে এটি ব্যবহার Collections.sort()করা আরও ভাল ও (নলগন) সমাধান।
amit

0

যদি আপনি List<Object>একটি সাব টাইপের একটি নাম ক্ষেত্রের অবজেক্টগুলি ধরে রাখতে ব্যবহার করছেন (নামটি উপ-টাইপটি কল করুন NamedObject), নামটি অ্যাক্সেস করার জন্য আপনাকে তালিকার উপাদানগুলি হ্রাস করতে হবে। আপনার কাছে 3 টি বিকল্প রয়েছে যার মধ্যে সেরাটি প্রথম:

  1. List<Object>আপনি যদি সহায়তা করতে পারেন তবে প্রথমে কোনওটি ব্যবহার করবেন না - আপনার নামযুক্ত জিনিসগুলিকে একটিতে রাখুনList<NamedObject>
  2. আপনার List<Object>উপাদানগুলিকে List<NamedObject>একটিতে অনুলিপি করুন, প্রক্রিয়াটিতে ডাউনকাস্টিং করুন, বাছাই করুন, তারপরে সেগুলি অনুলিপি করুন
  3. তুলনামূলকভাবে ডাউনকাস্টিং করুন

বিকল্প 3 এর মতো দেখতে পাবেন:

Collections.sort(p, new Comparator<Object> () {
        int compare (final Object a, final Object b) {
                return ((NamedObject) a).getName().compareTo((NamedObject b).getName());
        }
}

0
if(listAxu.size() > 0){
     Collections.sort(listAxu, new Comparator<Situacao>(){
        @Override
        public int compare(Situacao lhs, Situacao rhs) {            
            return lhs.getDescricao().compareTo(rhs.getDescricao());
        }
    });
 }

1
3 বছরের পুরানো প্রশ্নে কেবল ডাম্পিং কোডের চেয়ে বিস্তৃত করার বিষয়ে যত্নশীল?
ফাঁকা 14

0

@ ভিক্টরের উত্তরটি আমার পক্ষে কাজ করেছে এবং অ্যান্ড্রয়েডের কারওর পক্ষে দরকারী হলে কোটলিনে এটি পুনরায় পোস্ট করা হয়েছে।

if (list!!.isNotEmpty()) {
   Collections.sort(
     list,
     Comparator { c1, c2 -> //You should ensure that list doesn't contain null values!
     c1.name!!.compareTo(c2.name!!)
   })
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.