[java] Java에 SortedList가없는 이유는 무엇입니까?

Java에는 SortedSetSortedMap인터페이스가 있습니다. 둘 다 Java Collections 프레임 워크 에 속하며 요소에 액세스하는 정렬 된 방법을 제공합니다.

그러나 내 이해에는 SortedListJava 가 없습니다 . java.util.Collections.sort()목록을 정렬하는 데 사용할 수 있습니다 .

왜 그런 식으로 설계되었는지 아십니까?



답변

리스트 반복자는 가장 먼저리스트의 내부 순서 (일명 삽입 순서 ) 로리스트의 요소를 얻는다는 것을 보장 합니다. 더 구체적으로 말하면 요소를 삽입 한 순서 또는 목록을 조작 한 방법입니다. 정렬은 데이터 구조를 조작하는 것으로 볼 수 있으며 목록을 정렬하는 몇 가지 방법이 있습니다.

개인적으로 볼 때 유용한 순서대로 방법을 주문 합니다.

1. 대신 Set또는 사용을 고려하십시오.Bag

참고 : 이 옵션은 맨 위에 놓았습니다. 일반적으로하고 싶은 일이기 때문입니다.

정렬 된 세트 는 삽입시 컬렉션을 자동으로 정렬합니다 . 즉, 컬렉션에 요소를 추가하는 동안 정렬을 수행합니다. 또한 수동으로 정렬 할 필요가 없습니다.

또한 중복 요소에 대해 걱정할 필요가 없거나 TreeSet<T>대신 요소를 사용할 필요가 없다면 대신 사용할 수 있습니다 . 구현 SortedSet하고 NavigableSet인터페이스하며 목록에서 예상 한대로 작동합니다.

TreeSet<String> set = new TreeSet<String>();
set.add("lol");
set.add("cat");
// automatically sorts natural order when adding

for (String s : set) {
    System.out.println(s);
}
// Prints out "cat" and "lol"

자연스러운 순서를 원하지 않으면을 사용하는 생성자 매개 변수를 사용할 수 있습니다 Comparator<T>.

또한, 당신이 사용할 수있는 멀티 세트를 (라고도 가방 ) , 그건입니다 Set대신에 중복 요소를 허용하는 그들의 타사 구현이있다. 가장 주목할만한로부터 구아바 라이브러리TreeMultiset등 많은 작품을, TreeSet.

2. 목록을 정렬하십시오 Collections.sort()

위에서 언급했듯이 Lists 정렬은 데이터 구조의 조작입니다. 따라서 다양한 방법으로 정렬되는 “한 가지 진실의 원천”이 필요한 상황에서는 수동으로 정렬하는 것이 좋습니다.

java.util.Collections.sort()방법으로 목록을 정렬 할 수 있습니다 . 방법에 대한 코드 샘플은 다음과 같습니다.

List<String> strings = new ArrayList<String>()
strings.add("lol");
strings.add("cat");

Collections.sort(strings);
for (String s : strings) {
    System.out.println(s);
}
// Prints out "cat" and "lol"

비교기 사용

한 가지 분명한 이점은 당신이 사용할 수 있다는 것이다 Comparatorsort방법. Java는 로케일 구분 정렬 문자열에 유용한 Comparator것과 같은 일부 구현도 제공합니다 Collator. 다음은 하나의 예입니다.

Collator usCollator = Collator.getInstance(Locale.US);
usCollator.setStrength(Collator.PRIMARY); // ignores casing

Collections.sort(strings, usCollator);

동시 환경에서 정렬

sort컬렉션 인스턴스가 조작되므로 변경 불가능한 컬렉션 사용을 고려해야하므로 동시 사용 환경에서는 이 방법 을 사용하는 것이 쉽지 않습니다. 이것은 구아바가 Ordering수업 에서 제공 하는 것으로 간단한 원 라이너입니다.

List<string> sorted = Ordering.natural().sortedCopy(strings);

3. 당신의 목록을 포장 java.util.PriorityQueue

Java에는 정렬 된 목록이 없지만 정렬 대기열은 아마 당신에게 잘 작동 할 것입니다. 그것은이다 java.util.PriorityQueue클래스입니다.

Nico Haase는 의견 에이 답변에 관한 관련 질문에 연결했습니다 .

정렬 된 컬렉션 에서 내부 데이터 구조 를 조작하지 않으려는 경우가 많으 므로 PriorityQueue가 List 인터페이스를 구현하지 않는 이유는 요소에 직접 액세스 할 수 있기 때문입니다.

PriorityQueue반복자 에 대한 경고

PriorityQueue클래스의 구현 Iterable<E>Collection<E>는 평소와 같이 반복 할 수 있도록 인터페이스를 제공합니다. 그러나 이터레이터는 정렬 된 순서로 요소를 반환한다고 보장하지 않습니다. 대신 (Alderath가 주석에서 지적한 것처럼) poll()비어있을 때까지 대기열에 있어야합니다.

당신이를 통해 우선 순위 큐에 목록을 변환 할 수 있습니다 어떤 수집을 소요 생성자 :

List<String> strings = new ArrayList<String>()
strings.add("lol");
strings.add("cat");

PriorityQueue<String> sortedStrings = new PriorityQueue(strings);
while(!sortedStrings.isEmpty()) {
    System.out.println(sortedStrings.poll());
}
// Prints out "cat" and "lol"

4. 자신의 SortedList수업을 작성하십시오

참고 : 이 작업을 수행하지 않아도됩니다.

새 요소를 추가 할 때마다 정렬되는 고유 한 List 클래스를 작성할 수 있습니다. 이것은 구현에 따라 오히려 계산 무거운를 얻을 수 있습니다 및 무의미 하기 때문에 두 가지 이유, 당신이 연습으로 그것을하지 않으려면 :

  1. 메소드가 요소가 사용자가 지정한 색인에 상주하는지 확인해야하기 List<E>때문에 인터페이스가 갖는 계약을 위반 add합니다.
  2. 왜 바퀴를 재발 명합니까? 위의 첫 번째 지점에서 지적한대로 TreeSet 또는 Multisets를 대신 사용해야합니다.

그러나 연습으로 사용하려면 시작하기위한 코드 샘플이 있으며 AbstractList추상 클래스를 사용합니다 .

public class SortedList<E> extends AbstractList<E> {

    private ArrayList<E> internalList = new ArrayList<E>();

    // Note that add(E e) in AbstractList is calling this one
    @Override
    public void add(int position, E e) {
        internalList.add(e);
        Collections.sort(internalList, null);
    }

    @Override
    public E get(int i) {
        return internalList.get(i);
    }

    @Override
    public int size() {
        return internalList.size();
    }

}

필요한 메소드를 재정의하지 않은 경우 기본 구현은 AbstractList을 던집니다 UnsupportedOperationException.


답변

List의 개념은 자동 정렬 된 컬렉션의 개념과 호환되지 않기 때문입니다. List의 요점은 호출 한 후에 list.add(7, elem)대한 호출 list.get(7)이 반환 elem됩니다. 자동 정렬 목록을 사용하면 요소가 임의의 위치에있게됩니다.


답변

항목이 추가 된 순서 (FIFO 순서)에 따라 모든 목록이 이미 “정렬”되었으므로을 사용하여 요소의 자연 순서를 포함하여 다른 순서로 항목을 “정렬”할 수 있습니다 java.util.Collections.sort().

편집하다:

데이터 구조 등의 목록은 항목이 삽입되는 순서입니다 흥미로운에 근거하고 있습니다.

세트에는 해당 정보가 없습니다.

시간을 추가하여 주문하려면을 사용하십시오 List. 다른 기준을 사용하여 주문합니다 SortedSet.


답변

설정 및지도 비선형 데이터 구조입니다. 리스트는 선형 데이터 구조입니다.

여기에 이미지 설명을 입력하십시오


트리 데이터 구조 SortedSetSortedMap인터페이스 구현을 TreeSet하고 TreeMap각각 사용하여 레드 – 블랙 트리 구현 알고리즘을. 따라서 중복 항목 (또는 경우 키)이 없는지 확인합니다 Map.

  • List 이미 정렬 된 컬렉션 및 인덱스 기반 데이터 구조를 유지하고 있으며 트리는 인덱스 기반 데이터 구조가 아닙니다.
  • Tree 정의상 중복은 포함 할 수 없습니다.
  • 에서 List우리는 중복을 가질 수 있습니다, 그래서이 없다 TreeList(NO 즉 SortedList).
  • List는 요소를 삽입 순서대로 유지합니다. 따라서 목록을 정렬하려면을 사용해야 java.util.Collections.sort()합니다. 요소의 자연 순서에 따라 지정된 목록을 오름차순으로 정렬합니다.

답변

JavaFX SortedList

시간이 오래 걸렸지 만 Java 8에는 정렬되어 List있습니다.
http://docs.oracle.com/javase/8/javafx/api/javafx/collections/transformation/SortedList.html

javadocs에서 볼 수 있듯이 이는 JavaFX 콜렉션의 일부이며 ObservableList에 대해 정렬 된보기를 제공하기위한 것입니다.

업데이트 : Java 11에서는 JavaFX 툴킷이 JDK 외부로 이동했으며 이제 별도의 라이브러리입니다. JavaFX 11은 다운로드 가능한 SDK 또는 MavenCentral에서 제공됩니다. 참조 https://openjfx.io를


답변

2015 년 4 월 현재 모든 신규 사용자를 위해 Android 는 지원 라이브러리에으로 작업하도록 특별히 설계된 SortedList 클래스를 제공합니다 RecyclerView. 여기 블로그 게시물 이 있습니다.


답변

또 다른 요점은 삽입 작업의 시간 복잡성입니다. 목록 삽입의 경우 O (1)의 복잡성을 예상합니다. 그러나 정렬 된 목록으로는 보장 할 수 없습니다.

그리고 가장 중요한 점은 목록이 해당 요소에 대해 아무 것도 가정하지 않는다는 것입니다. 예를 들어, equals또는 구현하지 않은 것들의 목록을 만들 수 있습니다 compare.