Answers:
这来得很晚,但是JDK中只有一个类是为了拥有排序列表。它被命名(与其他Sorted*
接口有些混乱)“ java.util.PriorityQueue
”。它可以排序Comparable<?>
或使用Comparator
。
与List
sorted using 的不同之Collections.sort(...)
处在于,通过使用堆数据结构,这将始终保持部分顺序,具有O(log(n))插入性能,而在sorted中插入ArrayList
将为O(n)(即,使用二进制搜索和移动)。
但是,与不支持索引访问()不同的是List
,访问堆中项目的唯一方法是一次将它们取出(因此命名为)。PriorityQueue
get(5)
PriorityQueue
TreeMap和TreeSet将按排序顺序为您提供内容的迭代。或者,您可以使用ArrayList并使用Collections.sort()对其进行排序。所有这些类都在java.util中
如果你想保持一个排序列表,你会经常修改,当你需要插入的元素(即一个结构,除了进行排序,允许重复,其内容可以通过索引有效地引用),然后使用ArrayList但,请始终使用Collections.binarySearch()确定添加给定元素的索引。后一种方法告诉您需要插入的索引,以使列表保持排序。
使用Google Guava的TreeMultiset类。番石榴有一个壮观的收藏API。
提供保持排序顺序的List实现的一个问题是该add()
方法的JavaDocs中做出的承诺。
List
始终在末尾加上a的要求。
有一些选择。如果您不希望重复并且插入的对象具有可比性,我建议使用TreeSet。
您也可以使用Collections类的静态方法来执行此操作。
有关更多信息,请参见Collections#sort(java.util.List)和TreeSet。
如果只想对列表进行排序,请使用任何一种List并使用Collections.sort()。如果要确保列表中的元素是唯一的并且始终排序,请使用SortedSet。
我要做的是实现具有内部实例的List,该实例具有委派的所有方法。
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”,如果该元素不存在,该方法将插入适当的位置,或者替换该元素以防万一。
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”方法上引发和不受支持的操作异常。
public boolean add(Contact object) {
throw new UnsupportedOperationException("Use putOrdered instead");
}
...而且您还必须谨慎使用ListIterator方法,因为它们可能会修改您的内部列表。在这种情况下,您可以返回内部列表的副本,也可以再次引发异常。
public ListIterator<Contact> listIterator() {
return (new ArrayList<Contact>(list)).listIterator();
}
List
合同。也许最好只实施Collection
。而且如果ContactList
被排序,那么contains()
也可以使用来实现binarySearch
,从而更加高效。
实现所需排序列表的最有效方法是实现可索引的跳转列表,如下所示:Wikipedia:可索引的跳转列表。它将允许在O(log(n))中进行插入/删除操作,并允许同时进行索引访问。而且还允许重复。
跳过列表非常有趣,我想说是低估的数据结构。不幸的是,Java基库中没有索引的跳过列表实现,但是您可以使用一种开源实现,也可以自己实现。有常规的Skiplist实现,例如ConcurrentSkipListSet和ConcurrentSkipListMap
如果您使用Java 8的早期版本,则可以尝试使用LambdaJ解决这些任务。您可以在这里找到它: http //code.google.com/p/lambdaj/
这里有一个例子:
排序迭代
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());
}
});
用LambdaJ排序
List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge());
当然,具有这种美感会影响性能(平均2倍),但是您能找到更具可读性的代码吗?
Collections.sort(persons, (p1, p2) -> p1.getAge().compareTo(p2.getAge()));
//or
persons.sort((p1, p2) -> p1.getAge().compareTo(p2.getAge()));
-(p1.getAge().compareTo(p2.getAge()))
PriorityQueue的问题在于它由一个简单的数组备份,而按顺序获取元素的逻辑由“ queue [2 * n + 1]和queue [2 *(n + 1)]”事物完成。如果您只是拔掉头,它会很好用,但是如果您试图在某个时候在其上调用.toArray,它将使其无用。
我通过使用com.google.common.collect.TreeMultimap解决了此问题,但我为定值包装的值提供了自定义比较器,该值从不返回0。
例如 对于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()时就可以按顺序获取值,并且也有重复项。
您想要的是二叉搜索树。它保持排序顺序,同时提供对数搜索,删除和插入操作(除非您有退化的树-然后是线性的)。它非常容易实现,甚至可以使它实现List接口,但是索引访问变得很复杂。
第二种方法是先创建一个ArrayList,然后再进行冒泡排序。因为您一次要插入或删除一个元素,所以插入和删除的访问时间是线性的。搜索是对数和索引访问常量(LinkedList的时间可能不同)。您所需的唯一代码是5,也许是6行冒泡排序。
您可以使用Arraylist和Treemap,就像您所说的那样,您还需要重复的值,然后就不能使用TreeSet了,尽管TreeSet也进行了排序,但是您必须定义比较器。
对于Set,您可以使用TreeSet。TreeSet根据自然顺序或传递给该特定对象的Comparable的任何排序顺序对元素进行排序。对于地图,请使用TreeMap。TreeMap提供了对键的排序。为了将一个对象添加为TreeMap的键,该类应实现可比较的接口,从而强制实现具有排序顺序定义的compare()方法。 http://techmastertutorial.in/java-collection-impl.html
使用sort()方法对列表进行排序,如下所示:
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
按元素顺序排列的元素。或者Collection.sort()
用于与进行外部排序Comparator()
。
使用Java 8 Comparator,如果我们想对列表进行排序,则这是世界上人口最多的10个城市,我们希望按名称对它进行排序(如Time所报道)。日本大阪。墨西哥墨西哥城。... 中国北京。……巴西圣保罗。……印度孟买。... 上海,中国。……印度德里。... 日本东京。
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
public class SortCityList {
/*
* Here are the 10 most populated cities in the world and we want to sort it by
* name, as reported by Time. Osaka, Japan. ... Mexico City, Mexico. ...
* Beijing, China. ... São Paulo, Brazil. ... Mumbai, India. ... Shanghai,
* China. ... Delhi, India. ... Tokyo, Japan.
*/
public static void main(String[] args) {
List<String> cities = Arrays.asList("Osaka", "Mexico City", "São Paulo", "Mumbai", "Shanghai", "Delhi",
"Tokyo");
System.out.println("Before Sorting List is:-");
System.out.println(cities);
System.out.println("--------------------------------");
System.out.println("After Use of List sort(String.CASE_INSENSITIVE_ORDER) & Sorting List is:-");
cities.sort(String.CASE_INSENSITIVE_ORDER);
System.out.println(cities);
System.out.println("--------------------------------");
System.out.println("After Use of List sort(Comparator.naturalOrder()) & Sorting List is:-");
cities.sort(Comparator.naturalOrder());
System.out.println(cities);
}
}
根据用户定义的标准对ArrayList进行排序。
型号类别
class Student
{
int rollno;
String name, address;
public Student(int rollno, String name, String address)
{
this.rollno = rollno;
this.name = name;
this.address = address;
}
public String toString()
{
return this.rollno + " " + this.name + " " + this.address;
}
}
分类等级
class Sortbyroll implements Comparator<Student>
{
public int compare(Student a, Student b)
{
return a.rollno - b.rollno;
}
}
主班
class Main
{
public static void main (String[] args)
{
ArrayList<Student> ar = new ArrayList<Student>();
ar.add(new Student(111, "bbbb", "london"));
ar.add(new Student(131, "aaaa", "nyc"));
ar.add(new Student(121, "cccc", "jaipur"));
System.out.println("Unsorted");
for (int i=0; i<ar.size(); i++)
System.out.println(ar.get(i));
Collections.sort(ar, new Sortbyroll());
System.out.println("\nSorted by rollno");
for (int i=0; i<ar.size(); i++)
System.out.println(ar.get(i));
}
}
输出量
Unsorted
111 bbbb london
131 aaaa nyc
121 cccc jaipur
Sorted by rollno
111 bbbb london
121 cccc jaipur
131 aaaa nyc