Java中的sorting集合

我是Java的初学者。 请build议可以/应该使用哪些集合来维护Java中的sorting列表。 我已经尝试过MapSet ,但他们不是我正在寻找的。

这很晚了,但是JDK中有一个类只是为了有一个sorting列表。 它被命名(与其他Sorted*接口有些不Sorted* )“ java.util.PriorityQueue ”。 它可以对Comparable<?> s进行sorting,也可以使用Comparable<?>器进行sorting。

与使用Collections.sort(...)sorting的List不同的是,这将通过使用堆数据结构来始终保持部分顺序,具有O(log(n))插入性能,而插入sortingArrayList将是O(n)(即使用二进制search和移动)。

但是,与List不同, PriorityQueue不支持索引访问( get(5) ), 访问堆中项的唯一方法是逐个取出 (因此名为PriorityQueue )。

TreeMap和TreeSet将按照sorting顺序给出一个迭代内容。 或者您可以使用ArrayList并使用Collections.sort()对其进行sorting。 所有这些类都在java.util中

如果你想维护一个你经常要修改sorting列表 (例如,除了被sorting,允许重复和其元素可以被索引高效地引用的结构),然后使用一个ArrayList,但是当你需要插入一个元素,总是使用Collections.binarySearch()来确定添加给定元素的索引 。 后一种方法告诉你需要插入的索引,以便按照sorting顺序保存你的列表。

使用谷歌Guava的TreeMultiset。 番石榴是一个壮观的collectionsAPI。

番石榴: https : //github.com/google/guava

TreeMultiset: https ://google.github.io/guava/releases/snapshot/api/docs/com/google/common/collect/TreeMultiset.html

提供一个维护sorting顺序的List实现的一个问题是在'add'方法的Javadoc中做出的承诺。

有几个选项。 如果你不想重复和你插入的对象是可比较的,我会build议TreeSet。

您也可以使用Collections类的静态方法来执行此操作。

有关更多信息,请参阅Collections#sort(java.util.List)和TreeSet 。

您需要SortedSet实现,即TreeSet 。

如果您只是想对列表进行sorting,请使用任何types的列表并使用Collections.sort() 。 如果你想确保列表中的元素是唯一的并且总是被sorting,使用SortedSet 。

我所做的是实现列表具有所有方法委托内部实例。

  public class ContactList implements List<Contact>, Serializable { private static final long serialVersionUID = -1862666454644475565L; private final List<Contact> list; public ContactList() { super(); this.list = new ArrayList<Contact>(); } public ContactList(List<Contact> list) { super(); //copy and order list List<Contact>aux= new ArrayList(list); Collections.sort(aux); this.list = aux; } public void clear() { list.clear(); } public boolean contains(Object object) { return list.contains(object); } 

之后,我实现了一个新的方法“putOrdered”,如果元素不存在或者在它存在的情况下将其replace,则插入适当的位置。

 public void putOrdered(Contact contact) { int index=Collections.binarySearch(this.list,contact); if(index<0){ index= -(index+1); list.add(index, contact); }else{ list.set(index, contact); } } 

如果你想允许重复的元素只是实现addOrdered(或两者)。

 public void addOrdered(Contact contact) { int index=Collections.binarySearch(this.list,contact); if(index<0){ index= -(index+1); } list.add(index, contact); } 

如果你想避免插入,你也可以在“add”和“set”方法上抛出不支持的操作exception。

 public boolean add(Contact object) { throw new UnsupportedOperationException("Use putOrdered instead"); } 

…还必须小心使用ListIterator方法,因为它们可以修改您的内部列表。 在这种情况下,您可以返回内部列表的副本或再次抛出exception。

 public ListIterator<Contact> listIterator() { return (new ArrayList<Contact>(list)).listIterator(); } 

TreeSet不起作用,因为它们不允许重复,并且不提供在特定位置获取元素的方法。 PriorityQueue不起作用,因为它不允许在特定位置获取元素,这是列表的基本要求。 我认为你需要实现你自己的algorithm来维护Java中的sorting列表O(logn)插入时间,除非你不需要重复。 也许一个解决scheme可能会使用一个TreeMap,其中的键是项目的子类覆盖equals方法,以便允许重复。

使用LambdaJ

如果您使用的是Java 8之前的版本,则可以使用LambdaJ尝试解决这些任务。您可以在此处find它: http : //code.google.com/p/lambdaj/

这里有一个例子:

sorting迭代

 List<Person> sortedByAgePersons = new ArrayList<Person>(persons); Collections.sort(sortedByAgePersons, new Comparator<Person>() { public int compare(Person p1, Person p2) { return Integer.valueOf(p1.getAge()).compareTo(p2.getAge()); } }); 

用LambdaJsorting

 List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge()); 

当然,这样的美performance会对性能产生影响(平均2次),但是你能find更易读的代码吗?

使用lambdaexpression式与java 8sorting

 Collections.sort(persons, (p1, p2) -> p1.getAge().compareTo(p2.getAge())); //or persons.sort((p1, p2) -> p1.getAge().compareTo(p2.getAge())); 

PriorityQueue的问题在于它是由一个简单的数组来备份的,通过“queue [2 * n + 1]和queue [2 *(n + 1)]”thingie完成获取元素的逻辑。 如果你只是从头开始,那么它就很好用,但是如果你想在某个时候调用.toArray就没用了。

我通过使用com.google.common.collect.TreeMultimap解决了这个问题,但是我提供了一个自定义的比较器,这些值封装在一个Ordering中,永远不会返回0。

恩。 for Double:

 private static final Ordering<Double> NoEqualOrder = Ordering.from(new Comparator<Double>() { @Override public int compare(Double d1, Double d2) { if (d1 < d2) { return -1; } else { return 1; } } }); 

这样,当我调用.toArray()时,我得到的值,也有重复。

像你想要实现一个sorting列表的最有效的方法是实现可索引skiplist,如下所示: Wikipedia:Indexable skiplist 。 它将允许在O(log(n))中插入/删除,并允许同时进行索引访问。 而且它也允许重复。

跳过列表是一个非常有趣的,我会说,低估数据结构。 不幸的是,在Java基础库中没有跳过列表的实现,但是您可以使用其中一个开源实现或者自己实现它。

你想要的是一个二叉search树。 它保持sorting的顺序,同时为search,移除和插入提供对数访问(除非你有一个退化的树 – 那么它是线性的)。 这很容易实现,甚至可以使其实现List接口,但是索引访问变得复杂。

第二种方法是有一个ArrayList,然后是一个冒泡sorting实现。 因为您一次插入或删除一个元素,所以插入和删除的访问时间是线性的。 search是对数和索引访问常量(对于LinkedList,时间可能不同)。 你需要的唯一的代码是5,也许6行的冒泡sorting。

你可以使用Arraylist和Treemap,正如你所说的你想要重复的值,那么你不能使用TreeSet,虽然它也被sorting,但你必须定义比较器。

使用sort()方法对列表进行sorting,如下所示:

 List list = new ArrayList(); //add elements to the list Comparator comparator = new SomeComparator(); Collections.sort(list, comparator); 

参考请参阅链接: http : //tutorials.jenkov.com/java-collections/sorting.html

使用TreeSet ,以sorting顺序给出元素。 或者使用Collection.sort()Comparator()进行外部sorting。

 import java.util.TreeSet; public class Ass3 { TreeSet<String>str=new TreeSet<String>(); str.add("dog"); str.add("doonkey"); str.add("rat"); str.add("rabbit"); str.add("elephant"); System.out.println(str); }