列表迭代器首先保证您按照列表的内部顺序(也称为列表)获取列表的元素。插入顺序)。更具体地说,它是按照您插入元素的顺序或您如何操作列表的顺序。排序可以看作是对数据结构的操作,有多种方法可以对列表进行排序。
我将按照以下顺序排列方法用处我个人认为:
1.考虑使用Set
or Bag
取而代之的是集合
NOTE:我将此选项放在顶部,因为无论如何这都是您通常想要做的。
已排序的集合在插入时自动对集合进行排序,这意味着它会在您将元素添加到集合中时进行排序。这也意味着您不需要手动对其进行排序。
此外,如果您确定不需要担心(或有)重复元素,那么您可以使用TreeSet<T>反而。它实现了SortedSet
and 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>.
或者,您可以使用多组(也称为Bags), 这是一个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 in the sort
方法。 Java还提供了一些实现Comparator
如那个Collator这对于区域设置敏感的排序字符串很有用。这是一个例子:
Collator usCollator = Collator.getInstance(Locale.US);
usCollator.setStrength(Collator.PRIMARY); // ignores casing
Collections.sort(strings, usCollator);
并发环境中的排序
请注意,尽管使用sort
方法在并发环境中并不友好,因为集合实例将被操作,您应该考虑使用不可变集合。这是 Guava 提供的Ordering类,是一个简单的单行:
List<string> sorted = Ordering.natural().sortedCopy(strings);
3. 用以下内容包装你的清单java.util.PriorityQueue
虽然 Java 中没有排序列表,但是有一个排序队列可能同样适合您。它是java.util.PriorityQueue class.
尼科·哈斯 (Nico Haase) 在评论中链接到相关问题这也回答了这个问题。
在已排序的集合中你很可能不想操纵内部数据结构,这就是 PriorityQueue 不实现 List 接口的原因(因为这将使您可以直接访问其元素)。
警告PriorityQueue
迭代器
The PriorityQueue
类实现了Iterable<E>
and 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
class
NOTE:你不应该这样做。
您可以编写自己的 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
s.