Bir Liste <Nesne> Nesne adı alanını kullanarak alfabetik olarak nasıl sıralanır


103

. Gibi bir Nesneler Listem var. List<Object> pBu listeyi Nesne adı alanını kullanarak alfabetik olarak sıralamak istiyorum. Nesne 10 alan içerir ve ad alanı bunlardan biridir.

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());
        }
    } );
}

Ama String.compare gibi bir şey yok ..?


3
İsmi nasıl anlayacaksın? - Objectisimleri yok. Kullanmayı mı kastediyorsun .toString()?
Matt Fenwick

object1ve object2türünde olması gerekir Campaignve karşılaştırma işlevi object1.getName().compareTo(object2.getName()).
Bart van Heukelom

Sen karıştır List<Object>ve Comparator<Campaign>. Bunu yapamazsınız. Ya varsa List<Object>ve Comparator<Object>ya List<Campaign>veComparator<Campaign>
viktor

Yanıtlar:


231

Kodunuzdan, Comparatorzaten ile parametrelendirilmiş gibi görünüyor Campaign. Bu sadece birlikte çalışacaktır List<Campaign>. Ayrıca, aradığınız yöntem 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());
      }
  });
}

Veya Java 1.8 kullanıyorsanız

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

Son bir yorum - liste boyutunu kontrol etmenin bir anlamı yok. Sıralama boş bir liste üzerinde çalışacaktır.


2
Bence bu, her şeyi OP'nin aradığı şeye dönüştüren en iyi cevap. Ve yorumlardan, büyük / küçük harfe duyarlı olmasını istediğini düşünüyorum, bu yüzden sadece CompareTo'yu karşılaştırmak için değiştirinToIgnoreCase
Greg Case

İlk çözümde küçük bir gelişme: eğer (list.size ()> 1) yapabiliriz - 1 öğe için sıralamaya gerek yok ..
Rami Yampolsky

12
KullanabilirsinizComparator.comparing(Campaign::getName)
Jose Da Silva

4
list.sort((object1, object2) -> object1. getName().compareTo(object2. getName()));benim için çalıştı
Lucas

1
sortedList = list.stream().sort((object1, object2) -> object1. getName().compareTo(object2. getName()))..collect(Collectors.toList());Yeni bir sıralı liste almak için kullanmayı deneyin
Lukas

16

Dizeleri alfabetik olarak sıralamanın en doğru yolu Collator, uluslararasılaştırma nedeniyle kullanmaktır . Birkaç ekstra karakter nedeniyle bazı dillerin sıraları farklıdır.

   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());
        }
       });
   }

Uluslararasılaştırma kullanımını önemsemiyorsanız 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

Bir göz atın Collections.sort()veComparator arayüze .

Dize karşılaştırma ile yapılabilir object1.getName().compareTo(object2.getName())ya daobject2.getName().compareTo(object1.getName()) (eğer arzu sıralama yönüne bağlı olarak).

Sıralamanın durumdan bağımsız olmasını istiyorsanız, yapın object1.getName().toUpperCase().compareTo(object2.getName().toUpperCase()).


ve nasıl denir bu alanı ayıklanması öneririz do namadan Objecttürü? bu cevap tam değil.
amit

İsim çıkarma, nesnenin türüne bağlıdır. Sanırım sadece bir yer tutucu türü. Daha somut bir tür veremezseniz, yansımayı kullanmayı bırakabilirsiniz.
tobiasbayer


7
public class ObjectComparator implements Comparator<Object> {

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

}

Lütfen Nesneyi , ad alanı içeren sınıfınızla değiştirin

Kullanım:

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

Bunu yaptım ama "testler" "Arama" dan önce geliyor.: (((
Saurabh Kumar

Ters sıralama yapmak istiyorsanız, sadece karşılaştırıcı sınıfında obj1.getName().compareTo(obj2.getName()ile değiştirinobj2.getName().compareTo(obj1.getName()
Jan Vorcak

2

gibi bir şey

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

2

Burada Robert B'nin cevabının, List<T>Reflection kullanan ve 3. taraf kitaplıkları olmayan nesnenin belirli bir String özelliği için çalışan ve ona göre sıralayan bir sürümü bulunmaktadır.

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

Sen kullanabilirsiniz sortThisBy()gelen Eclipse Koleksiyon :

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

Listenin türünü aşağıdakilerden değiştiremezseniz List:

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

Not: Eclipse Koleksiyonlarına katkıda bulunuyorum.


2

Bunu dene:

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

Bilginize, bunu Android'de yapıyorsanız, en azından API seviyesi 24 gerektirir
MSpeed

1

Nesnelerinizin ortak bir atası varsa [öyle olsun T] List<T>yerine kullanmalı List<Object>ve bir Karşılaştırıcı uygulamalısınız bu T için , ad alanını kullanarak.

Ortak bir atanız yoksa, bir Comperator uygulayabilir ve yansıma kullanabilirsiniz. ve adı çıkarmak için olmadığını, önerilmediğini ve yansımayı kullanmak için kötü performans gösterdiğini unutmayın, ancak bir alan adına erişmenize izin verir nesnenin gerçek türü hakkında hiçbir şey bilmeden [ilgili ada sahip bir alana sahip olmasının yanı sıra]

Her iki durumda da, sıralamak için Collections.sort () kullanmanız gerekir .


1

Yazıyı yapmanın başka bir yolunu buldum.

if(listAxu.size() > 0){
    Collections.sort(listAxu, Comparator.comparing(IdentityNamed::getDescricao));
}

0

Bu, amit tarafından açıklandığı gibi , YourClassyerine bir liste varsaymaktadır .Object

Bu biti Google Guava kitaplığından kullanabilirsiniz:

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

Söz eden diğer cevaplar Comparatorberi yanlış değildir Orderinguygular Comparator. Bence bu çözüm biraz daha kolay, ancak yeni başlayan biriyseniz ve kitaplıkları ve / veya "işlevsel programlamayı" kullanmaya alışkın değilseniz daha zor olabilir.

Kendi soruma bu cevaptan utanmadan kopyaladım .


Ben böyle yaparım, ancak OP için çok fazla olabilir.
Greg Case

0

Bir seçim Sıralama kullanma

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) Tekerleği neden yeniden icat etsin? neyin var Collections.sort()? (2) liste tiptedir List<Object>ve bu nedenle list.get(j).getName()derlenmeyecektir. (3) bu çözüm O (n ^ 2) iken, kullanmak Collections.sort()daha iyi bir O (nlogn) çözümdür.
amit

0

List<Object>Bir ad alanı olan bir alt türün nesnelerini tutmak için kullanıyorsanız (alt türü çağıralım NamedObject), ada erişmek için liste öğelerini aşağıya indirmeniz gerekir. En iyisi ilki olmak üzere 3 seçeneğiniz var:

  1. List<Object>Yardım edebiliyorsanız ilk etapta a kullanmayın - adlandırılmış nesnelerinizi birList<NamedObject>
  2. List<Object>Öğelerinizi List<NamedObject>süreç içinde aşağı doğru bir şekilde kopyalayın , sıralayın ve ardından geri kopyalayın
  3. Karşılaştırıcıda aşağı doğru tahmin yapın

3. Seçenek şöyle görünecektir:

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 yıllık bir soruda sadece kodu atmaktansa ayrıntılarına girmek ister misiniz?
Holloway

0

@ Victor'un cevabı benim için işe yaradı ve Android kullanan bir başkası için yararlı olması durumunda burada Kotlin'de yeniden yayınladı.

if (list!!.isNotEmpty()) {
   Collections.sort(
     list,
     Comparator { c1, c2 -> //You should ensure that list doesn't contain null values!
     c1.name!!.compareTo(c2.name!!)
   })
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.