• 比较器中的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)我还不知道具体是什么意思,是强制类型转换吗? 如果有大佬看到我的文章请评论告知,万分感谢

  • 相关阅读:
    POJ 2251 Dungeon Master(BFS)
    POJ 1321 棋盘问题 (DFS + 回溯)
    POJ 3009 Curling 2.0(DFS + 模拟)
    Codeforces 702D Road to Post Office(模拟 + 公式推导)
    Codeforces 702A Maximum Increase(dp)
    Codeforces 702C Cellular Network(二分)
    Codeforces 702B Powers of Two
    POJ 3083 Children of the Candy Corn (DFS + BFS + 模拟)
    POJ 2488 A Knight's Journey (回溯法 | DFS)
    POJ1094 Sorting It All Out (拓扑排序)
  • 原文地址:https://www.cnblogs.com/Joey777210/p/11862963.html
Copyright © 2020-2023  润新知