리스트 반복자는 가장 먼저리스트의 내부 순서 (일명 삽입 순서 ) 로리스트의 요소를 얻는다는 것을 보장 합니다. 더 구체적으로 말하면 요소를 삽입 한 순서 또는 목록을 조작 한 방법입니다. 정렬은 데이터 구조를 조작하는 것으로 볼 수 있으며 목록을 정렬하는 몇 가지 방법이 있습니다.
개인적으로 볼 때 유용한 순서대로 방법을 주문 합니다.
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
.