オブジェクト名フィールドを使用してList <Object>をアルファベット順にソートする方法


102

次のようなオブジェクトのリストがありList<Object> pます。オブジェクト名フィールドを使用してこのリストをアルファベット順に並べ替えたいです。オブジェクトには10​​個のフィールドがあり、名前フィールドはその1つです。

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()ですか?
Matt Fenwick、2011

object1そして、object2タイプである必要がCampaignあり、比較関数ですobject1.getName().compareTo(object2.getName())
Bart van Heukelom、2011

あなたは混合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());
      }
  });
}

または、Java 1.8を使用している場合

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

最後のコメント-リストのサイズをチェックしても意味がありません。ソートは空のリストで機能します。


2
これは、OPが探しているものにすべてを抽出する最良の答えだと思います。コメントから、彼は大文字と小文字を区別しないことを望んでいると思うので、compareToをcompareToIgnoreCaseに切り替えます
Greg Case

マイナーは、最初の溶液中で改善:(はlist.size()> 1)場合、我々は行うことができます-ソートする必要はありません1つの項目のよう...
ラミYampolsky

12
使用できますComparator.comparing(Campaign::getName)
Jose Da Silva、

4
list.sort((object1, object2) -> object1. getName().compareTo(object2. getName()));私のために働きました
Lucas

1
を使用sortedList = list.stream().sort((object1, object2) -> object1. getName().compareTo(object2. getName()))..collect(Collectors.toList());して、新しい並べ替えられたリストを取得してみてください
Lukas

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か?この答えは完全ではありません。
2011

名前の抽出は、オブジェクトのタイプによって異なります。それは単なるプレースホルダータイプだと思いました。より具体的なタイプを指定できない場合は、反射の使用を終了する可能性があります。
tobiasbayer 2011


7
public class ObjectComparator implements Comparator<Object> {

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

}

Objectを、名前フィールドを含むクラスに置き換えてください

使用法:

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

私はこれを行いましたが、「テスト」が「検索」の前に来ています。:(((
Saurabh Kumar

あなたが逆のソートメイクoをしたい場合は、単に置き換えるobj1.getName().compareTo(obj2.getName()obj2.getName().compareTo(obj1.getName()、コンパレータのクラスで
月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>Reflectionを使用し、サードパーティのライブラリを使用せずにオブジェクトの指定されたStringプロパティに対して機能し、ソートするRobert Bの回答のバージョンです。

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

注:私はEclipseコレクションの寄稿者です。


2

これを試して:

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

あなたは、Androidでこれをやっている場合はFYI、それは少なくともAPIレベル24が必要です
MSpeed

1

オブジェクトに共通の祖先がある場合は、代わりにを使用し、名前フィールドを使用して、このTのコンパレータを実装するT必要があります。List<T>List<Object>

共通の祖先がない場合は、Comperatorを実装し、リフレクションを使用て名前を抽出できます。リフレクションを使用すると、安全でなく、推奨されず、パフォーマンスが低下しますが、フィールド名にアクセスできます。オブジェクトの実際のタイプについては何も知らない[​​関連する名前のフィールドがあることを除いて]

どちらの場合も、Collections.sort()を使用してソートする必要があります。


1

タイプを実行する別の方法を見つけました。

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

0

これは、amitで説明されているようYourClassObject、ではなくのリストを想定しています。

Google Guavaライブラリからこのビットを使用できます:

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

について言及してComparatorいる他の回答は、をOrdering実装してComparatorいるため、正しくあります。私の意見では、このソリューションは少し簡単ですが、初心者でライブラリや「関数型プログラミング」の使用に慣れていない場合は難しいかもしれません。

私自身の質問のこの答えから恥知らずにコピーしました


これは私のやり方ですが、OPにとっては多すぎるかもしれません。
グレッグケース

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()ですか?(2)リストはタイプList<Object>であるため、list.get(j).getName()コンパイルされません。(3)このソリューションはO(n ^ 2)ですが、使用Collections.sort()するとより良いO(nlogn)ソリューションになります。
アミット

0

List<Object>名前フィールドを持つサブタイプのオブジェクトを保持するためにを使用している場合(これをサブタイプと呼びNamedObjectましょう)、名前にアクセスするためにリスト要素をダウンキャストする必要があります。あなたには3つのオプションがあり、そのうちの最良のものは最初のものです:

  1. List<Object>助けることができるなら最初にa を使わないでください-名前付きオブジェクトを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年前の質問でコードを単にダンプするのではなく、詳しく説明したいですか?
Holloway、2015年

0

@Victorの回答は私にとってはうまくいき、Androidを実行している他の誰かに役立つ場合に備えて、ここKotlinに再投稿しました。

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.