Java 如何在 SortedSet<> 上定义比较器,如 TreeSet<>?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38066291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to define comparator on SortedSet<> like TreeSet<>?
提问by Saurabh Gupta
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. So i went and searched on google and found out that treeSet is better and i can use its predefined comparator method.
并意识到 SortedSet 是一个抽象类,我必须在其中实现 comapartor 方法。所以我去谷歌搜索,发现 treeSet 更好,我可以使用它的预定义比较器方法。
2) SortedSet<String> words = new TreeSet<String>(){}
When went to java docs i realized that TreeSet extends AbstractSet rather than 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). Question 2 -how to define comparator of SortedSet which will work as TreeSet. So here is the working code with TreeSet
当去 Java 文档时,我意识到 TreeSet 扩展了 AbstractSet 而不是 SortedSet。问题 1 -任何人都可以解释第二行如何仍然有效(就像我没有概括我通常会做的 Set 而是我使用两个完全不同的类,没有父子关系)。 问题 2 -如何定义将作为 TreeSet 工作的 SortedSet 的比较器。所以这是 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? I understand that if there is natural ordering i don't need to define a new comparator.
我基本上想学习,如何在使用SortedSet 时在 TreeSet 中制作一个基本的比较器“like” ?我知道如果有自然排序,我不需要定义新的比较器。
采纳答案by kazenorin
Answer 1:
答案 1:
TreeSet<T>
implements the NavigableSet<T>
interface, which extends SortedSet<T>
who also extends Set<T>
.
TreeSet<T>
实现NavigableSet<T>
接口,该接口扩展SortedSet<T>
who 也扩展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>
,您可以省略Comparator
for TreeSet
,因为“自然排序”是指使用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));
回答by toro
TreeSet implements NavigableSet, which in turn extends SortedSet, which is why line 2) works. See TreeSet Java doc.
TreeSet 实现了 NavigableSet,后者又扩展了 SortedSet,这就是第 2) 行起作用的原因。请参阅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);
}
}
回答by Saravana
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
默认情况下,排序将基于自然排序完成,并且基本原语包装器 ( Integer, Long, ...
) 实现了Comparable
接口,因此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
一旦你添加第二个元素就会被抛出
回答by dasblinkenlight
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>
is a NavigableSet<T>
,并且NavigableSet<T>
is a 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>
使用由T
的实现提供的自然顺序Comparable<T>
。