简体   繁体   English

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

[英]How to define comparator on SortedSet<> like TreeSet<>?

I want to make a lexical sorted list of strings, so i went with the basic SortedSet 我想制作一个词汇排序的字符串列表,所以我选择了基本的SortedSet

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

and realized that SortedSet is an abstract class, in which I will have to implement the comapartor method. 并意识到SortedSet是一个抽象类,我将不得不实现comapartor方法。 So i went and searched on google and found out that treeSet is better and i can use its predefined comparator method. 所以我去google搜索并发现treeSet更好,我可以使用它预定义的比较器方法。

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

When went to java docs i realized that TreeSet extends AbstractSet rather than SortedSet. 当去了java文档时,我意识到TreeSet扩展了AbstractSet而不是SortedSet。 Question 1 - Can anyone explain how the 2nd line is still working(like i am not generalizing the Set which i would normally do instead i am using two totally different Classes with no Parent child relation). 问题1 -任何人都可以解释第二行是如何工作的(就像我没有概括我通常会做的集合,而是使用两个完全不同的类,没有父子关系)。 Question 2 - how to define comparator of SortedSet which will work as TreeSet. 问题2 -如何定义SortedSet的比较器,它将用作TreeSet。 So here is the working code with 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());
    }

Normal Input 正常输入

welcometojava
3

Expected Output 预期产出

com
eto
jav
wel

Edit-1 For the answer of Question 2, i am expecting something like this 编辑-1对于问题2的答案,我期待这样的事情

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

I basically want to learn, how to make a basic comparator "like" in TreeSet while using SortedSet ? 我基本上想学习,如何在使用SortedSet时在TreeSet中创建一个基本的比较器“like”? I understand that if there is natural ordering i don't need to define a new comparator. 我知道如果有自然顺序,我不需要定义一个新的比较器。

Answer 1 : 答案1

TreeSet<T> implements the NavigableSet<T> interface, which extends SortedSet<T> who also extends Set<T> . TreeSet<T>实现了NavigableSet<T>接口,该接口扩展了也扩展了Set<T> SortedSet<T> Set<T>

The interfaces themselves doesn't actually do the sorting, the concrete class does. 接口本身实际上并不进行排序,具体类也是如此。

So: 所以:

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

You would still have them in sorted order. 您仍然可以按顺序排列它们。

Answer 2 : 答案2

Firstly, for classes that already implement Comparable<T> , you can omit the Comparator for the TreeSet , as "Natural Ordering" is meant by using the Comparable<T> 's compareTo method. 首先,对于已经实现Comparable<T> ,可以省略TreeSetComparator ,因为“Natural Ordering”是指使用Comparable<T>compareTo方法。

Otherwise you can supply a Comparator instance to as the TreeMap constructor's first argument: 否则,您可以将Comparator实例作为TreeMap构造函数的第一个参数提供:

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

or use Java 8 Lambdas: 或使用Java 8 Lambdas:

    Set<String> myStrings = new TreeSet<>((o1, o2) -> o1.compareTo(o2));

To answer your question, 要回答你的问题,

TreeSet also implements NavigableSet which extends SortedSet TreeSet还实现了扩展SortedSet的NavigableSet

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

public interface NavigableSet<E> extends SortedSet<E>

By default sort will be done based on natural ordering and the basic primitives wrappers ( Integer, Long, ... ) implements Comparable interface, so no need to implement the Comparable if the collection holds wrappers of Primitives and natural ordering is expected 默认情况下,sort将基于自然顺序完成,基本原语包装器( Integer, Long, ... )实现Comparable接口,因此如果集合包含Primitives的包装器并且预期自然顺序,则无需实现Comparable

But your custom class should implement Comparable if it should be ordered in TreeSet else ClassCastException will be thrown once you add the second element 但是你的自定义类应该实现Comparable,如果它应该在TreeSet排序,否则一旦添加第二个元素就会抛出ClassCastException

TreeSet implements NavigableSet, which in turn extends SortedSet, which is why line 2) works. TreeSet实现了NavigableSet,后者又扩展了SortedSet,这就是第2行的工作原理。 See TreeSet Java doc . 请参阅TreeSet Java文档

For the second part, try this: 对于第二部分,试试这个:

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);
    }

}

SortedSet<T> is not an abstract class, it is an interface. SortedSet<T>不是抽象类,它是一个接口。

TreeSet<T> does implement SortedSet<T> , but not directly: the chain of inheritance goes as follows: TreeSet<T>确实实现了SortedSet<T> ,但不是直接实现:继承链如下:

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

That is why the assignment SortedSet<String> words = new TreeSet<String>() works: TreeSet<T> is a NavigableSet<T> , and NavigableSet<T> is a SortedSet<T> , so the assignment is legal. 这就是为什么赋值SortedSet<String> words = new TreeSet<String>()工作原理: TreeSet<T>是一个NavigableSet<T> ,而NavigableSet<T>是一个SortedSet<T> ,因此赋值是合法的。

When you do not supply an explicit comparator, TreeSet<T> 's uses natural ordering supplied by T 's implementation of Comparable<T> . 当您不提供显式比较器时, TreeSet<T>使用TComparable<T>实现提供的自然顺序。

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

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