与列表<String> 字段相当class
Comparable class with a List<String> field
我有一个简单的 class,它存储一个整数和一个字符串列表。
因为我想在TreeSet<>
中使用这个class,那个必须是Comparable
。
但是当尝试使用 Java 8 Comparator
class 时,我无法比较我的内部列表。
我有以下错误:
Bad return type in method reference: cannot convert java.util.List to U
我认为有一种非常简单的方法可以做到这一点,但我找不到。
怎么做?
public class MyClass implements Comparable<MyClass> {
private final int someInt;
private final List<String> someStrings;
public MyClass (List<String> someStrings, int someInt) {
this.someInt = someInt;
this.someStrings = new ArrayList<>(someStrings);
}
@Override
public int compareTo(MyClass other) {
return
Comparator.comparing(MyClass::getSomeInt)
.thenComparing(MyClass::getSomeStrings) // Error here
.compare(this, other);
}
public int getSomeInt() {
return someInt;
}
public List<String> getSomeStrings() {
return someStrings;
}
}
编辑 1
我只想以最简单的方式比较字符串列表(隐式使用 String.compareTo()
)。
请注意,我现在确实想对我的 List<String>
进行排序,但我希望它是 Comparable
,以便 MyClass
也具有可比性,最后,我可以插入 MyClass
实例到 TreeSet<MyClass>
.
A 还在 Java文档中看到以下内容:
java.util.Comparator<T> public Comparator<T>
thenComparing(@NotNull Comparator<? super T> other)
For example, to sort a collection of String based on the length and then case-insensitive natural ordering, the comparator can be composed using following code,
Comparator<String> cmp = Comparator.comparingInt(String::length)
.thenComparing(String.CASE_INSENSITIVE_ORDER);
这似乎是一个线索,但我不知道如何将它应用到这个简单的例子中。
编辑 2
假设我希望按以下方式对 List<String>
进行排序:
- 首先检查:
List.size()
(小的小于大的);
- 第二次检查大小是否匹配:逐个比较两个列表的每个元素,直到找到
String.compareTo
方法 returns 1 或 -1 的一个。
如何在我的 compareTo
方法中使用 lambda 表达式?
编辑 3
这不会重复 因为我想知道如何构建一个 class 的比较器,其中包含一个 List<String>
和 Java 8 链接 Comparable
来电。
所以要比较列表,首先检查长度,然后逐个比较两个列表中具有相同索引的每个项目,对吗?
(即[a, b, c] < [b, a, c]
)
为列表创建自定义比较器 return 连接您的列表字符串:
Comparator<List<String>> listComparator = (l1, l2) -> {
if (l1.size() != l2.size()) {
return l1.size() - l2.size();
}
for (int i = 0; i < l1.size(); i++) {
int strCmp = l1.get(i).compareTo(l2.get(i));
if (strCmp != 0) {
return strCmp;
}
}
return 0; // Two list equals
};
然后您可以使用自定义比较器进行比较:
@Override
public int compareTo(MyClass other) {
return Comparator.comparing(MyClass::getSomeInt)
.thenComparing(Comparator.comparing(MyClass:: getSomeStrings , listComparator))
.compare(this, other);
}
如果你想要[a, b, c] = [b, a, c]
,那么你必须在比较之前先对这些列表进行排序:
public String getSomeStringsJoined() {
return getSomeStrings().stream().sort(Comparator.naturalOrder()).collect(Collectors.joining());
}
我有一个简单的 class,它存储一个整数和一个字符串列表。
因为我想在TreeSet<>
中使用这个class,那个必须是Comparable
。
但是当尝试使用 Java 8 Comparator
class 时,我无法比较我的内部列表。
我有以下错误:
Bad return type in method reference: cannot convert java.util.List to U
我认为有一种非常简单的方法可以做到这一点,但我找不到。
怎么做?
public class MyClass implements Comparable<MyClass> {
private final int someInt;
private final List<String> someStrings;
public MyClass (List<String> someStrings, int someInt) {
this.someInt = someInt;
this.someStrings = new ArrayList<>(someStrings);
}
@Override
public int compareTo(MyClass other) {
return
Comparator.comparing(MyClass::getSomeInt)
.thenComparing(MyClass::getSomeStrings) // Error here
.compare(this, other);
}
public int getSomeInt() {
return someInt;
}
public List<String> getSomeStrings() {
return someStrings;
}
}
编辑 1
我只想以最简单的方式比较字符串列表(隐式使用 String.compareTo()
)。
请注意,我现在确实想对我的 List<String>
进行排序,但我希望它是 Comparable
,以便 MyClass
也具有可比性,最后,我可以插入 MyClass
实例到 TreeSet<MyClass>
.
A 还在 Java文档中看到以下内容:
java.util.Comparator<T> public Comparator<T>
thenComparing(@NotNull Comparator<? super T> other)
For example, to sort a collection of String based on the length and then case-insensitive natural ordering, the comparator can be composed using following code,
Comparator<String> cmp = Comparator.comparingInt(String::length)
.thenComparing(String.CASE_INSENSITIVE_ORDER);
这似乎是一个线索,但我不知道如何将它应用到这个简单的例子中。
编辑 2
假设我希望按以下方式对 List<String>
进行排序:
- 首先检查:
List.size()
(小的小于大的); - 第二次检查大小是否匹配:逐个比较两个列表的每个元素,直到找到
String.compareTo
方法 returns 1 或 -1 的一个。
如何在我的 compareTo
方法中使用 lambda 表达式?
编辑 3
这不会重复 List<String>
和 Java 8 链接 Comparable
来电。
所以要比较列表,首先检查长度,然后逐个比较两个列表中具有相同索引的每个项目,对吗?
(即[a, b, c] < [b, a, c]
)
为列表创建自定义比较器 return 连接您的列表字符串:
Comparator<List<String>> listComparator = (l1, l2) -> {
if (l1.size() != l2.size()) {
return l1.size() - l2.size();
}
for (int i = 0; i < l1.size(); i++) {
int strCmp = l1.get(i).compareTo(l2.get(i));
if (strCmp != 0) {
return strCmp;
}
}
return 0; // Two list equals
};
然后您可以使用自定义比较器进行比较:
@Override
public int compareTo(MyClass other) {
return Comparator.comparing(MyClass::getSomeInt)
.thenComparing(Comparator.comparing(MyClass:: getSomeStrings , listComparator))
.compare(this, other);
}
如果你想要[a, b, c] = [b, a, c]
,那么你必须在比较之前先对这些列表进行排序:
public String getSomeStringsJoined() {
return getSomeStrings().stream().sort(Comparator.naturalOrder()).collect(Collectors.joining());
}