문제

주소록 응용 프로그램에 대한 정렬 기능을 구현하려고합니다.

나는 정렬하고 싶다 ArrayList<Contact> contactArray. Contact 이름, 주택 번호, 휴대폰 번호 및 주소의 네 개의 필드가 포함 된 클래스입니다. 나는 정리하고 싶다 name.

이를 위해 사용자 정렬 함수를 어떻게 작성할 수 있습니까?

도움이 되었습니까?

해결책

다음은 개체 주문에 관한 자습서입니다.

나는 몇 가지 예를 제시하지만 어쨌든 그것을 읽는 것이 좋습니다.


정렬하는 다양한 방법이 있습니다 ArrayList. 정의하려면 a 자연스러운 (기본) 주문, 그런 다음 당신은 허용해야합니다 Contact 구현하다 Comparable. 기본적으로 정렬하고 싶다고 가정합니다 name, 그런 다음 (단순성을 위해 NullChecks 생략) :

public class Contact implements Comparable<Contact> {

    private String name;
    private String phone;
    private Address address;

    public int compareTo(Contact other) {
        return name.compareTo(other.name);
    }

    // Add/generate getters/setters and other boilerplate.
}

당신이 할 수 있도록

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

Collections.sort(contacts);

정의하려면 외부 제어 가능한 주문 (자연 순서를 무시한 경우) 그러면 Comparator:

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

// Now sort by address instead of name (default).
Collections.sort(contacts, new Comparator<Contact>() {
    public int compare(Contact one, Contact other) {
        return one.getAddress().compareTo(other.getAddress());
    }
}); 

당신은 심지어 정의 할 수도 있습니다 Comparators에서 Contact 매번 재현하는 대신 재사용 할 수 있도록 자체적으로 :

public class Contact {

    private String name;
    private String phone;
    private Address address;

    // ...

    public static Comparator<Contact> COMPARE_BY_PHONE = new Comparator<Contact>() {
        public int compare(Contact one, Contact other) {
            return one.phone.compareTo(other.phone);
        }
    };

    public static Comparator<Contact> COMPARE_BY_ADDRESS = new Comparator<Contact>() {
        public int compare(Contact one, Contact other) {
            return one.address.compareTo(other.address);
        }
    };

}

다음과 같이 사용할 수 있습니다.

List<Contact> contacts = new ArrayList<Contact>();
// Fill it.

// Sort by address.
Collections.sort(contacts, Contact.COMPARE_BY_ADDRESS);

// Sort later by phone.
Collections.sort(contacts, Contact.COMPARE_BY_PHONE);

그리고 상단을 크림을 만들기 위해, 당신은 일반적인 Javabean 비교기:

public class BeanComparator implements Comparator<Object> {

    private String getter;

    public BeanComparator(String field) {
        this.getter = "get" + field.substring(0, 1).toUpperCase() + field.substring(1);
    }

    public int compare(Object o1, Object o2) {
        try {
            if (o1 != null && o2 != null) {
                o1 = o1.getClass().getMethod(getter, new Class[0]).invoke(o1, new Object[0]);
                o2 = o2.getClass().getMethod(getter, new Class[0]).invoke(o2, new Object[0]);
            }
        } catch (Exception e) {
            // If this exception occurs, then it is usually a fault of the developer.
            throw new RuntimeException("Cannot compare " + o1 + " with " + o2 + " on " + getter, e);
        }

        return (o1 == null) ? -1 : ((o2 == null) ? 1 : ((Comparable<Object>) o1).compareTo(o2));
    }

}

다음과 같이 사용할 수 있습니다.

// Sort on "phone" field of the Contact bean.
Collections.sort(contacts, new BeanComparator("phone"));

(코드에서 볼 수 있듯이, 널 필드는 이미 정렬 중에 NPE를 피하기 위해 이미 덮여 있습니다)

다른 팁

이미 게시 된 내용 외에도 Java 8 이후 코드를 단축하고 다음과 같이 쓸 수 있음을 알아야합니다.

Collection.sort(yourList, Comparator.comparing(YourClass::getFieldToSortOn));

또는 지금 목록 이후 sort 방법

yourList.sort(Comparator.comparing(YourClass::getFieldToSortOn));

설명:

Java 8이므로 기능적 인터페이스 (하나의 초록 방법 만있는 인터페이스 - 더 많은 기본 또는 정적 메소드를 가질 수 있음)를 사용하여 쉽게 구현할 수 있습니다.

부터 Comparator<T> 하나의 추상 방법 만 있습니다 int compare(T o1, T o2) 기능 인터페이스입니다.

대신 (예제에서 @balusc 대답)

Collections.sort(contacts, new Comparator<Contact>() {
    public int compare(Contact one, Contact other) {
        return one.getAddress().compareTo(other.getAddress());
    }
}); 

이 코드를 다음으로 줄일 수 있습니다.

Collections.sort(contacts, (Contact one, Contact other) -> {
     return one.getAddress().compareTo(other.getAddress());
});

우리는 건너 뛰면 이것 (또는 어떤) 람다를 단순화 할 수 있습니다.

  • 인수 유형 (Java는 메소드 서명에 따라이를 추론합니다)
  • 또는 {return ... }

그래서 대신

(Contact one, Contact other) -> {
     return one.getAddress().compareTo(other.getAddress();
}

우리는 쓸 수있다

(one, other) -> one.getAddress().compareTo(other.getAddress())

또한 지금 Comparator 정적 메소드와 같은 정적 방법이 있습니다 comparing(FunctionToComparableValue) 또는 comparing(FunctionToValue, ValueComparator) 우리는 객체의 특정 값을 비교 해야하는 비교기를 쉽게 만들기 위해 사용할 수 있습니다.

즉, 우리는 위의 코드를 다시 작성할 수 있습니다

Collections.sort(contacts, Comparator.comparing(Contact::getAddress)); 
//assuming that Address implements Comparable (provides default order).

이 페이지 ArrayList와 같은 컬렉션 정렬에 대해 알아야 할 모든 것을 알려줍니다.

기본적으로 당신은 필요합니다

  • 너의 ~을 만들어라 Contact 클래스 구현 Comparable 인터페이스
    • 메소드 생성 public int compareTo(Contact anotherContact) 그 안에.
  • 이 작업을 수행하면 전화 할 수 있습니다 Collections.sort(myContactList);,
    • 어디 myContactList ~이다 ArrayList<Contact> (또는 다른 컬렉션 Contact).

비교기 클래스 만들기와 관련된 또 다른 방법이 있으며 링크 된 페이지에서도 읽을 수 있습니다.

예시:

public class Contact implements Comparable<Contact> {

    ....

    //return -1 for less than, 0 for equals, and 1 for more than
    public compareTo(Contact anotherContact) {
        int result = 0;
        result = getName().compareTo(anotherContact.getName());
        if (result != 0)
        {
            return result;
        }
        result = getNunmber().compareTo(anotherContact.getNumber());
        if (result != 0)
        {
            return result;
        }
        ...
    }
}

Balusc와 Bguiz는 이미 Java의 내장 비교기를 사용하는 방법에 대한 매우 완전한 답변을 제공했습니다.

Google 수집에는 an이 있다고 추가하고 싶습니다 주문 표준 비교기보다 "강력한"클래스. 체크 아웃 할 가치가 있습니다. 객체에 대한 함수 결과에 따라 순서를 복리하는 것과 같은 시원한 일을 할 수 있습니다.

여기 그 이점 중 일부를 언급하는 블로그 게시물입니다.

연락처 클래스를 구현해야합니다 유사한, 그런 다음 구현합니다 compareTo(Contact) 방법. 그렇게하면 Collections.sort가 정렬 할 수 있습니다. 링크 된 페이지에 따라 '비교는이 객체가 지정된 객체보다 또는 더 크기 때문에 부정적인 정수, 0 또는 양의 정수를 반환합니다.'

예를 들어, 이름 (A에서 Z)별로 정렬하고 싶다면 수업은 다음과 같습니다.

public class Contact implements Comparable<Contact> {

    private String name;

    // all the other attributes and methods

    public compareTo(Contact other) {
        return this.name.compareTo(other.name);
    }
}

사용하여 람다 즈 다음과 같이 연락처 모음 (예 : 이름으로)을 정렬 할 수 있습니다.

sort(contacts, on(Contact.class).getName());

또는 주소로 :

sort(contacts, on(Contacts.class).getAddress());

등등. 일반적으로 일부 조건에 따라 연락처를 필터링하거나 그룹화하는 등 여러 가지 방법으로 컬렉션에 액세스하고 조작 할 수있는 DSL을 제공합니다.

Collections.sort는 좋은 정렬 구현입니다. 연락처를 위해 비슷한 구현이없는 경우 비교기 구현

참고 :

분류 알고리즘은 수정 된 Mergesort입니다 (낮은 하위 목록에서 가장 높은 요소가 높은 하위 목록에서 가장 낮은 요소보다 적은 경우 병합이 생략됩니다). 이 알고리즘은 보장 된 N 로그 (N) 성능을 제공합니다. 지정된 목록은 수정 가능해야하지만 RESINIVE를 사용할 필요는 없습니다. 이 구현은 지정된 목록을 배열로 덤프하고 배열을 정렬하며 배열의 해당 위치에서 각 요소를 재설정하는 목록 위에 반복합니다. 이것은 링크 된 목록을 제자리에 정렬하려고 시도하는 N2 로그 (N) 성능을 피합니다.

Merge 정렬은 아마도 대부분의 검색 알고리즘보다 낫습니다.

나는 다음과 같이했다. 번호와 이름은 두 개의 Arraylist입니다. 이름을 정렬해야합니다. 어떤 변경이 Arralist 순서로 이름이 이루어지면 숫자 Arraylist도 순서를 변경합니다.

public void sortval(){

        String tempname="",tempnum="";

         if (name.size()>1) // check if the number of orders is larger than 1
            {
                for (int x=0; x<name.size(); x++) // bubble sort outer loop
                {
                    for (int i=0; i < name.size()-x-1; i++) {
                        if (name.get(i).compareTo(name.get(i+1)) > 0)
                        {

                            tempname = name.get(i);

                            tempnum=number.get(i);


                           name.set(i,name.get(i+1) );
                           name.set(i+1, tempname);

                            number.set(i,number.get(i+1) );
                            number.set(i+1, tempnum);


                        }
                    }
                }
            }



}

이 방법을 사용하십시오 :

private ArrayList<myClass> sortList(ArrayList<myClass> list) {
    if (list != null && list.size() > 1) {
        Collections.sort(list, new Comparator<myClass>() {
            public int compare(myClass o1, myClass o2) {
                if (o1.getsortnumber() == o2.getsortnumber()) return 0;
                return o1.getsortnumber() < o2.getsortnumber() ? 1 : -1;
            }
        });
    }
    return list;
}

`

그리고 사용 : mySortedlist = sortList(myList);수업에서 비교기를 구현할 필요가 없습니다. 역 순서 교환을 원한다면 1 그리고 -1

배열을 사용합니다. 포함 된 클래스는 비교할 수 있어야합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top