개체 이름 필드를 사용하여 List <Object>를 알파벳순으로 정렬하는 방법


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()합니까?
Matt Fenwick 2011

object1object2필요 유형이어야합니다 Campaign, 그리고 기능이 비교 object1.getName().compareTo(object2.getName()).
Bart van Heukelom 2011

당신은 혼합 List<Object>하고 Comparator<Campaign>. 당신은 그렇게 할 수 없습니다. 어느 쪽이든, 당신은 List<Object>하고 Comparator<Object>List<Campaign>하고Comparator<Campaign>
빅토르

답변:


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
나는 이것이 OP가 찾고있는 모든 것을 추출하는 최선의 대답이라고 생각합니다. 그리고 의견에서, 나는 그래서 그냥 compareToIgnoreCase에 compareTo와 스위치, 그가 대소 문자를 구분하려는 생각
그렉 케이스

첫 번째 솔루션에서 사소한 개선 : if (list.size ()> 1)-1 개 항목에 대해서는 정렬 할 필요가 없습니다.
Rami Yampolsky

12
당신은 사용할 수 있습니다Comparator.comparing(Campaign::getName)
호세 다 실바에게

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무엇입니까? 이 대답은 완전하지 않습니다.
amit

이름 추출은 개체 유형에 따라 다릅니다. 그냥 자리 표시 자 유형이라고 생각했습니다. 더 구체적인 유형을 제공 할 수 없으면 반사 사용을 종료 할 수 있습니다.
tobiasbayer 2011


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

나는 그러나 "검색"을하기 전에오고있다 "시험"보다 이런 짓을 : (((.
Saurabh 쿠마

당신이 역 정렬 메이크업 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 CollectionssortThisBy() 에서 사용할 수 있습니다 .

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

에서 목록 유형을 변경할 수없는 경우 List:

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

참고 : 저는 Eclipse Collections의 기고자입니다.


2

이 시도:

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

참고로 Android에서이 작업을 수행하는 경우 API 레벨 24 이상이 필요합니다
MSpeed

1

객체에 공통 조상 T이있는 경우 List<T>대신을 사용하고 이름 필드를 사용하여이 T에 List<Object>대한 비교기 를 구현 해야 합니다.

공통 조상이없는 경우 Comperator를 구현하고 리플렉션 을 사용하여 이름을 추출 할 수 있습니다. 안전하지 않고 권장되지 않으며 리플렉션을 사용하는 데 성능이 좋지 않지만 필드 이름에 액세스 할 수 있습니다. 개체의 실제 유형에 대해 알지 못함 [관련 이름의 필드가 있다는 사실 외에]

두 경우 모두 Collections.sort () 를 사용 하여 정렬 해야합니다 .


1

유형을 수행하는 다른 방법을 찾았습니다.

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

0

이것은 amit에 의해 설명 된대로 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. 이 솔루션은 제 생각에는 좀 더 쉽습니다. 초보자이고 라이브러리 및 / 또는 "기능적 프로그래밍"을 사용하는 데 익숙하지 않은 경우 더 어려울 수 있습니다.

이 답변에서 내 질문에 뻔뻔스럽게 복사했습니다 .


이것은 내가 할 방법이지만 OP에는 너무 많을 수 있습니다.
Greg Case

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)이고 using Collections.sort()은 더 나은 O (nlogn) 솔루션입니다.
amit

0

를 사용하여 List<Object>이름 필드가있는 하위 유형의 객체를 보유하는 경우 (subtype을 호출 할 수 있음 NamedObject) 이름에 액세스하려면 목록 요소를 다운 캐스트해야합니다. 세 가지 옵션이 있으며 그중 가장 좋은 것은 첫 번째입니다.

  1. List<Object>도움이된다면 처음부터 a 를 사용하지 마십시오 .List<NamedObject>
  2. 당신의 복사 List<Object>에 요소를 List<NamedObject>정렬을 수행하는 과정에서 downcasting, 다시 복사
  3. Comparator에서 다운 캐스팅 수행

옵션 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

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.