与列表<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> 进行排序:

如何在我的 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());
}