具有List <string>字段的可比较类

时间:2018-05-16 09:41:05

标签: java-8 comparable

我有一个简单的类,它存储一个整数和一个字符串列表。

由于我想在TreeSet<>中使用此类,因此必须为Comparable。 但是在尝试使用Java 8 Comparator类时,我无法比较我的内部列表。 我有以下错误:

  

方法引用中的错误返回类型:无法将java.util.List转换为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还在JavaDoc中看到了以下内容:

java.util.Comparator<T> public Comparator<T>
    thenComparing(@NotNull Comparator<? super T> other)
  

例如,要根据长度和不区分大小写的自然顺序对String集合进行排序,可以使用以下代码组合比较器,

Comparator<String> cmp = Comparator.comparingInt(String::length)
   .thenComparing(String.CASE_INSENSITIVE_ORDER);

这似乎是一个线索,但我不知道如何将它应用于这个简单的例子。

编辑2

假设我希望我的List<String>按以下方式排序:

  • 首先检查:List.size()(较短者小于较大者);
  • 再次检查大小是否匹配:逐一比较两个列表中的每个元素,直到找到String.compareTo方法返回1或-1的位置。

如何在我的compareTo方法中使用lambdas进行此操作?

编辑3

这不会重复this question,因为我想知道如何构建一个类的比较器,其中包含List<String>,其中包含Java 8链接Comparable调用。

1 个答案:

答案 0 :(得分:1)

那么为了比较列表,首先检查长度,然后将两个列表中相同索引的每个项目逐一进行比较吧?

(即[a, b, c] < [b, a, c]

为列表字符串的列表返回连接创建自定义比较器:

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