如何在SortedSet上定义比较器<>像TreeSet<>?

时间:2016-06-28 02:51:48

标签: java collections set

我想制作一个词汇排序的字符串列表,所以我选择了基本的SortedSet

1)  Set<String> words = new SortedSet<String>(){}

并意识到SortedSet是一个抽象类,我必须在其中实现comapartor方法。所以我去google搜索并发现treeSet更好,我可以使用它预定义的比较器方法。

2)  SortedSet<String> words = new TreeSet<String>(){}

当去了java文档时,我意识到TreeSet扩展了AbstractSet而不是SortedSet。 问题1 - 任何人都可以解释第二行是如何工作的(就像我没有概括我通常会做的那样,而是使用两个完全不同的类,没有父子关系)。  问题2 - 如何定义SortedSet的比较器,它将用作TreeSet。所以这是使用TreeSet的工作代码

SortedSet<String> words = new TreeSet<>();
    Scanner scanner1 = new Scanner(System.in);
    String s1 = scanner1.nextLine();
    int a = scanner1.nextInt();
    while(s1.length()>a){
        words.add(s1.substring(0,a));
        s1 = s1.substring(a);
    }
    Iterator itr  = words.iterator();
    while(itr!= null&&itr.hasNext()){
        System.out.println(itr.next());
    }

正常输入

welcometojava
3

预期产出

com
eto
jav
wel

编辑-1 对于问题2的答案,我期待这样的事情

Set<String> words = new SortedSet<String>() {
        @Override
        public Comparator<? super String> comparator() {
            return null;
        }
        ......

我基本上想学习如何使用 SortedSet 在TreeSet中制作一个基本的比较器“喜欢”?我知道如果有自然顺序,我不需要定义一个新的比较器。

4 个答案:

答案 0 :(得分:7)

回答1

TreeSet<T>实现了NavigableSet<T>界面,该界面扩展了SortedSet<T>,并扩展了Set<T>

接口本身并没有实际进行排序,具体类就是这样做。

所以:

Set<String> myStrings = new TreeSet<>();
// Add a bunch of strings
// ...
for (String s : myStrings) {
 System.out.println(s);
}

你仍然可以按顺序排列它们。

回答2

首先,对于已经实施Comparable<T>的类,您可以省略Comparator的{​​{1}},&#34;自然排序&#34;是指使用TreeSet Comparable<T>方法。

否则,您可以提供compareTo实例作为TreeMap构造函数的第一个参数:

Comparator

或使用Java 8 Lambdas:

    Set<String> myStrings = new TreeSet<>(new Comparator<String>() {
        @Override
        public int compare(String o1, String o2) {
            // Define comparing logic here
            return o1.compareTo(o2);
        }
    });

答案 1 :(得分:3)

要回答你的问题,

TreeSet还实现了扩展SortedSet

的NavigableSet
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable

public interface NavigableSet<E> extends SortedSet<E>

默认情况下,sort将基于自然排序完成,基本原语包装器(Integer, Long, ...)实现Comparable接口,因此如果集合保存包装器,则无需实现Comparable预期原始和自然顺序

但是你的自定义类应该实现Comparable,如果它应该在TreeSet中排序,那么在添加第二个元素后将抛出ClassCastException

答案 2 :(得分:2)

TreeSet实现了NavigableSet,后者又扩展了SortedSet,这就是第2行的工作原理。请参阅TreeSet Java doc

对于第二部分,试试这个:

SortedSet<String> ts = new TreeSet<String>(new TSComparator());

class TSComparator implements Comparator<String>{

    @Override
    public int compare(String str1, String str2) {
        return str1.compareTo(str2);
    }

}

答案 3 :(得分:2)

SortedSet<T>不是抽象类,它是一个接口。

TreeSet<T>确实实现SortedSet<T>,但不是直接实现:继承链如下:

Set<T> - SortedSet<T> - NavigableSet<T>

这就是作业SortedSet<String> words = new TreeSet<String>()有效的原因:TreeSet<T>NavigableSet<T>,而NavigableSet<T>SortedSet<T>,因此作业是合法的。

当您不提供明确的比较器时,TreeSet<T>使用T Comparable<T>的实现提供的自然顺序。