比较器中的comparing方法以及涉及到的知识

今天在学习Java核心技术集合程序清单9-3时遇到了问题。 代码如下

public class TreeSetTest {

    public static void main(String[] args) {
        SortedSet<Item> parts = new TreeSet<>();
        parts.add(new Item("Toaster", 1234));
        parts.add(new Item("Widget", 4562));
        parts.add(new Item("Modem", 9912));
        System.out.println(parts);
        
        NavigableSet<Item> sortByDescription = new TreeSet<Item>(Comparator.comparing(Item::getDescription));
        
        sortByDescription.addAll(parts);
        System.out.println(sortByDescription);
    }

}
public class Item implements Comparable<Item>{
    private String description;
    private int partNumber;
    
    public Item(String aDescroption,int aPartNumber) {
        description = aDescroption;
        partNumber = aPartNumber;
    }
    
    public String getDescription() {
        return description;
    }
    
    public String toString() {
        return "[description=" + description + ",partNumber=" + partNumber + "]";
    }
    
    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        Item other = (Item)obj;
        return Objects.equals(description, other.description) && partNumber == other.partNumber;
    }
    
    public int hasCode() {
        return Objects.hash(description,partNumber);
    }
    
    @Override
    public int compareTo(Item o) {
        int diff = Integer.compare(partNumber,o.partNumber);
        return diff != 0 ? diff : description.compareTo(o.description);
        
    }
    
}

可以看到,在主函数中定制了一个比较器来按照描述信息排序,在看这个比较器定义的源码时有些看不懂,所以回去查阅了关于lambda表达式、泛型等知识,在这里记录以下以便以后查阅

首先看源码

 public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
            Function<? super T, ? extends U> keyExtractor)
    {
        Objects.requireNonNull(keyExtractor);
        return (Comparator<T> & Serializable)
            (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    }

在这里涉及到的知识点在下面一一解析

1,泛型  

U extends Comparable<? super U>

在这里表示 U实现了Comparable接口,同时Comparable接口中的实例域是U的父类。

带有超类型super限定的通配符表示了域的下限,即可以接收U的超类的作为Comparable中参数的类型

带有子类型extends限定的通配符表示了U的上限,即U只能是实现了Comparable接口的子类。

2,函数式接口。 函数式接口是用来接收函数作为参数的,用于lambda

  这里的Function是一个函数式接口,是Java给出的,表示有一个T类型参数的函数。原型是

Function<T,R>

T是参数类型,R是返回类型。Function接口自带一个apply方法,R apply(T) ,表示由T参数得到R的返回。

3,这里参数传入的是Item::getDescription,对应函数式接口Function,该函数的返回值String类型对应T,所以源码中的comparaTo对应的是String.comparaTo (String实现了Comparable)

所以这个比较器的结果也应当是按照字典顺序排序的。

这里return后面的括号中的(Comparator<T> & Serializable)我还不知道具体是什么意思,是强制类型转换吗? 如果有大佬看到我的文章请评论告知,万分感谢

 

posted @ 2019-11-14 22:11  Joey777210  阅读(1028)  评论(0编辑  收藏  举报