किसी ऑब्जेक्ट की सूची फ़ील्ड का उपयोग करके सूची <ऑब्जेक्ट> वर्णानुक्रम में कैसे सॉर्ट करें


103

मेरे पास वस्तुओं की एक सूची है। 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());
        }
    } );
}

लेकिन String.compare जैसा कुछ नहीं है ..?


3
आप नाम कैसे ले रहे हैं? - Objectनाम नहीं हैं। क्या आप उपयोग करने का मतलब है .toString()?
मैट फेनविक

object1और object2प्रकार की जरूरत है Campaign, और तुलना समारोह है object1.getName().compareTo(object2.getName())
बार्ट वैन ह्युकेलोम

आप मिश्रण List<Object>और Comparator<Campaign>। आप ऐसा नहीं कर सकते। या तो आपके पास List<Object>और Comparator<Object>/ List<Campaign>औरComparator<Campaign>
viktor 15

जवाबों:


231

आपके कोड से, ऐसा लगता है कि आपका 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());
      }
  });
}

या यदि आप Java 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अंतर्राष्ट्रीयकरण के कारण, वर्णानुक्रम में तार को सॉर्ट करने का सबसे सही तरीका है । कुछ भाषाओं में कुछ अतिरिक्त पात्रों आदि के कारण अलग-अलग क्रम हैं।

   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प्रकार से निकालने का सुझाव देते हैं ? यह उत्तर पूर्ण नहीं है।
अमित

नाम निष्कर्षण वस्तु के प्रकार पर निर्भर करता है। मेरा मानना ​​है कि यह केवल एक प्लेसहोल्डर प्रकार है। यदि आप अधिक ठोस प्रकार नहीं दे सकते हैं, तो आप प्रतिबिंब का उपयोग कर सकते हैं।
टोबियासबेयर


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()
Jan Vorcak

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>परावर्तन और किसी तीसरे पक्ष के पुस्तकालयों का उपयोग करके ऑब्जेक्ट की एक निर्दिष्ट स्ट्रिंग संपत्ति द्वारा सॉर्ट करने और उसके लिए काम करता है

/**
 * 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

आप ग्रहण संग्रहsortThisBy() से उपयोग कर सकते हैं :

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

यदि आप सूची से प्रकार नहीं बदल सकते हैं List:

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

नोट: मैं कलेक्शन एक्लिप्स का योगदानकर्ता हूं।


2

इसे इस्तेमाल करे:

List< Object> myList = x.getName;
myList.sort(Comparator.comparing(Object::getName));

FYI करें यदि आप Android में ऐसा कर रहे हैं, तो इसके लिए कम से कम API स्तर 24
MSpeed

1

यदि आपकी वस्तुओं में कुछ सामान्य पूर्वज हैं [तो रहने दें T] आपको नाम फ़ील्ड का उपयोग करके इस T के लिए एक तुलनित्रList<T> का उपयोग करना चाहिए List<Object>, और एक तुलनित्र को लागू करना चाहिए ।

यदि आपके पास एक सामान्य पूर्वज नहीं है, तो आप एक कम्पेक्टर को लागू कर सकते हैं, और प्रतिबिंब का उपयोग कर सकते हैं नाम को निकालने के का , ध्यान दें कि यह असुरक्षित, असुरक्षित है, और प्रतिबिंब का उपयोग करने के लिए खराब प्रदर्शन से ग्रस्त है, लेकिन यह आपको फ़ील्ड नाम का उपयोग करने की अनुमति देता है वस्तु के वास्तविक प्रकार के बारे में कुछ भी जाने बिना [इस तथ्य के अलावा कि उसके पास प्रासंगिक नाम वाला क्षेत्र है]

दोनों ही मामलों में, आपको सॉर्ट करने के लिए Collections.sort () का उपयोग करना चाहिए ।



0

यह एक सूची है YourClass इसके बजाय कीObject , जैसा कि एमिट द्वारा समझाया गया है ।

आप Google Guava लाइब्रेरी से इस बिट का उपयोग कर सकते हैं:

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;

}

(१) वह पहिए को क्यों मजबूत करेगा? क्या बुराई है Collections.sort()? (2) सूची प्रकार की है List<Object>, और इसलिए list.get(j).getName()संकलित नहीं होगी। (3) यह समाधान O (n ^ 2) है, जबकि उपयोग Collections.sort()एक बेहतर O (nlogn) समाधान है।
अमित

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 साल पुराने प्रश्न में सिर्फ डंपिंग कोड के बजाय विस्तृत करने के लिए देखभाल?
होलोले

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!!)
   })
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.