Java에는 SortedSet
및 SortedMap
인터페이스가 있습니다. 둘 다 Java Collections 프레임 워크 에 속하며 요소에 액세스하는 정렬 된 방법을 제공합니다.
그러나 내 이해에는 SortedList
Java 가 없습니다 . 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()
위에서 언급했듯이 List
s 정렬은 데이터 구조의 조작입니다. 따라서 다양한 방법으로 정렬되는 “한 가지 진실의 원천”이 필요한 상황에서는 수동으로 정렬하는 것이 좋습니다.
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"
비교기 사용
한 가지 분명한 이점은 당신이 사용할 수 있다는 것이다 Comparator
에 sort
방법. 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 클래스를 작성할 수 있습니다. 이것은 구현에 따라 오히려 계산 무거운를 얻을 수 있습니다 및 무의미 하기 때문에 두 가지 이유, 당신이 연습으로 그것을하지 않으려면 :
- 메소드가 요소가 사용자가 지정한 색인에 상주하는지 확인해야하기
List<E>
때문에 인터페이스가 갖는 계약을 위반add
합니다. - 왜 바퀴를 재발 명합니까? 위의 첫 번째 지점에서 지적한대로 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
.
답변
설정 및지도 비선형 데이터 구조입니다. 리스트는 선형 데이터 구조입니다.
트리 데이터 구조 SortedSet
및 SortedMap
인터페이스 구현을 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
.