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