简体   繁体   English

Java:SortedMap,TreeMap,Comparable? 如何使用?

[英]Java: SortedMap, TreeMap, Comparable? How to use?

I have a list of objects I need to sort according to properties of one of their fields. 我有一个对象列表,我需要根据其中一个字段的属性进行排序。 I've heard that SortedMap and Comparators are the best way to do this. 我听说SortedMap和Comparators是最好的方法。

  1. Do I implement Comparable with the class I'm sorting, or do I create a new class? 我是否对我正在排序的类实现Comparable,还是创建一个新类?
  2. How do I instantiate the SortedMap and pass in the Comparator? 如何实例化SortedMap并传入Comparator?
  3. How does the sorting work? 排序如何工作? Will it automatically sort everything as new objects are inserted? 在插入新对象时它会自动对所有内容进行排序吗?

EDIT: This code is giving me an error: 编辑:这段代码给我一个错误:

private TreeMap<Ktr> collection = new TreeMap<Ktr>();

(Ktr implements Comparator<Ktr> ). (Ktr实现Comparator<Ktr> )。 Eclipse says it is expecting something like TreeMap<K, V> , so the number of parameters I'm supplying is incorrect. Eclipse说它期待类似TreeMap<K, V> ,所以我提供的参数数量不正确。

  1. The simpler way is to implement Comparable with your existing objects, although you could instead create a Comparator and pass it to the SortedMap . 更简单的方法是使用现有对象实现Comparable ,尽管您可以创建Comparator并将其传递给SortedMap
    Note that Comparable and Comparator are two different things; 请注意, ComparableComparator是两回事; a class implementing Comparable compares this to another object, while a class implementing Comparator compares two other objects. 实现一类Comparable比较this另一目的,而实施的一类Comparator进行比较的其他两个对象。
  2. If you implement Comparable , you don't need to pass anything special into the constructor. 如果实现Comparable ,则不需要将任何特殊内容传递给构造函数。 Just call new TreeMap<MyObject>() . 只需调用new TreeMap<MyObject>() ( Edit: Except that of course Maps need two generic parameters, not one. Silly me!) 编辑:除了当然Maps需要两个通用参数,而不是一个。傻我!)
    If you instead create another class implementing Comparator , pass an instance of that class into the constructor. 如果您改为创建另一个实现Comparator的类,则将该类的实例传递给构造函数。
  3. Yes, according to the TreeMap Javadocs . 是的,根据TreeMap Javadocs

Edit: On re-reading the question, none of this makes sense. 编辑:在重新阅读问题时,这一切都没有意义。 If you already have a list, the sensible thing to do is implement Comparable and then call Collections.sort on it. 如果你已经有了一个列表,那么明智的做法就是实现Comparable ,然后在其上调用Collections.sort No maps are necessary. 不需要地图。

A little code: 一点点代码:

public class MyObject implements Comparable<MyObject> {
    // ... your existing code here ...
    @Override
    public int compareTo(MyObject other) {
        // do smart things here
    }
}

// Elsewhere:
List<MyObject> list = ...;
Collections.sort(list);

As with the SortedMap , you could instead create a Comparator<MyObject> and pass it to Collections.sort(List, Comparator) . SortedMap ,您可以创建Comparator<MyObject>并将其传递给Collections.sort(List, Comparator)

1. 1。

That depends on the situation. 这取决于具体情况。 Let's say the object A should sort before the object B in your set. 假设对象A应该在集合中的对象B之前排序。 If it generally makes sense to consider A less than B, then implementing Comparable would make sense. 如果考虑A小于B通常是有意义的,那么实现Comparable是有意义的。 If the order only makes sense in the context in which you use the set, then you should probably create a Comparator. 如果订单仅在您使用该集合的上下文中有意义,那么您应该创建一个Comparator。

2. 2。

new TreeMap(new MyComparator());

Or without creating a MyComparator class: 或者不创建MyComparator类:

new TreeMap(new Comparator<MyClass>() {
    int compare(MyClass o1, MyClass o2) { ... }
});

3. Yes. 是的。

Since you have a list and get an error because you have one argument on the map I suppose you want a sorted set: 由于你有一个列表并且因为你在地图上有一个参数而得到一个错误,我想你想要一个有序集:

SortedSet<Ktr> set = new TreeSet<Ktr>(comparator);

This will keep the set sorted, ie an iterator will return the elements in their sort order. 这将使set保持排序,即迭代器将按其排序顺序返回元素。 There are also methods specific to SortedSet which you might want to use. 您还可以使用特定于SortedSet的方法。 If you also want to go backwards you can use NavigableSet . 如果您还想倒退,可以使用NavigableSet

My answer assumes you are using the TreeMap implementation of SortedMap . 我的回答假设您正在使用SortedMapTreeMap实现。

1.) If using TreeMap , you have a choice. 1.)如果使用TreeMap ,您可以选择。 You can either implement Comparable directly on your class or pass a separate Comparator to the constructor. 您可以直接在类上实现Comparable也可以将单独的Comparator传递给构造函数。

2.) Example: 2.)示例:

Comparator<A> cmp = new MyComparator();
Map<A,B> map = new TreeMap<A,B>(myComparator);

3.) Yes that's correct. 3.)是的,这是正确的。 Internally TreeMap uses a red-black tree to store elements in order as they are inserted; 内部TreeMap使用红黑树在插入元素时按顺序存储元素; the time cost of performing an insert (or retrieval) is O(log N). 执行插入(或检索)的时间成本是O(log N)。

You make a Comparator<ClassYouWantToSort> . 您制作Comparator<ClassYouWantToSort> Then the Comparator compares the field that you want to sort on. 然后比较器比较要排序的字段。

When you create the TreeMap , you create a TreeMap<ClassYouWantToSort> , and you pass in the Comparator as an argument. 创建TreeMap ,将创建TreeMap<ClassYouWantToSort> ,并将Comparator作为参数传递。 Then, as you insert objects of type ClassYouWantToSort , the TreeMap uses your Comparator to sort them properly. 然后,当您插入ClassYouWantToSort类型的对象时, TreeMap使用您的Comparator对它们进行正确排序。

EDIT: As Adamski notes, you can also make ClassYouWantToSort itself Comparable . 编辑:正如Adamski所说,你也可以使ClassYouWantToSort本身具有Comparable The advantage is that you have fewer classes to deal with, the code is simpler, and ClassYouWantToSort gets a convenient default ordering. 优点是您可以处理更少的类,代码更简单, ClassYouWantToSort可以获得方便的默认排序。 The disadvantage is that ClassYouWantToSort may not have a single obvious ordering, and so you'll have to implement Comparables for other situations anyway. 缺点是ClassYouWantToSort可能没有一个明显的排序,因此无论如何你必须为其他情况实现Comparables You also may not be able to change ClassYouWantToSort . 您也可能无法更改ClassYouWantToSort

EDIT2: If you only have a bunch of objects that you're throwing into the collection, and it's not a Map (ie it's not a mapping from one set of objects to another) then you want a TreeSet , not a TreeMap . 编辑2:如果你只有一堆你投入集合的对象,并且它不是一个Map (即它不是从一组对象到另一组对象的映射),那么你需要一个TreeSet ,而不是TreeMap

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM