Java 集合工具类

问:简单说说 Comparable 和 Comparator 的区别和场景?

答:Comparable 对实现它的每个类的对象进行整体排序,这个接口需要类本身去实现,若一个类实现了 Comparable 接口,实现 Comparable 接口的类的对象的 List 列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序,此外实现 Comparable 接口的类的对象可以用作有序映射(如TreeMap)中的键或有序集合(如TreeSet)中的元素而不需要指定比较器, 实现 Comparable 接口必须修改自身的类(即在自身类中实现接口中相应的方法),如果我们使用的类无法修改(如 SDK 中一个没有实现 Comparable 的类),我们又想排序,就得用到 Comparator 这个接口了(策略模式)。所以如果你正在编写一个值类,它具有非常明显的内在排序关系,比如按字母顺序、按数值顺序或者按年代顺序,那你就应该坚决考虑实现 Comparable 这个接口, 若一个类实现了 Comparable 接口就意味着该类支持排序,而 Comparator 是比较器,我们若需要控制某个类的次序,可以建立一个该类的比较器来进行排序。Comparable 比较固定,和一个具体类相绑定,而 Comparator 比较灵活,可以被用于各个需要比较功能的类使用,所以尽量推荐使用 Comparator 而不是 Comparable,因为这样可以保证单一职责原则。

问:简单说说 Collection 和 Collections 的区别?

答:java.util.Collection 是一个集合接口,它提供了对集合对象进行基本操作的通用接口方法,在 Java 类库中有很多具体的实现,意义是为各种具体的集合提供最大化的统一操作方式。 譬如 Collection 的实现类有 List、Set 等,List 的实现类有 LinkedList、ArrayList、Vector 等,Vector 的实现类有 Stack 等,不过切记 Map 是自立门户的,其提供了转换为 Collection 的方法,但是自己不是 Collection 的子类。

java.util.Collections 是一个包装类,它包含有各种有关集合操作的静态多态方法,此类构造 private 不能实例化,就像一个工具类,服务于 Java 的 Collection 框架,其提供的方法大概可以分为对容器接口对象进行操作类(查找和替换、排序和调整顺序、添加和修改)和返回一个容器接口对象类(适配器将其他类型的数据转换为容器接口对象、装饰器修饰一个给定容器接口对象增加某种性质)。

问:Collections.emptyList() 与 new ArrayList() 有什么区别?

答:相同点为都是 AbstractList 的子类,都可以序列化。区别为 Collections.emptyList() 返回一个不可变的 List,而new ArrayList() 返回的 List 是可变的。只有当确实需要返回一个不可变空 List 时才使用Collections.emptyList(),多次调用 Collections.emptyList() 只会返回同一个 List 实例,而多次调用 new ArrayList() 每次都会返回新的实例。对于 emptySet() 和 emptyMap() 等类似方法有同样的结论适用。具体说服力如下源码所示:

        public static final  List emptyList () {
            return (List) EMPTY_LIST;
        }

        //EmptyList为Collections的一个内部类,为不可变列表 
        public static final List EMPTY_LIST = new EmptyList<>();

因此如下代码会抛出 UnsupportedOperationException 异常:

        public class Demo {
            public static void main(String[] args) {
                List list = Collections.emptyList();
                list.add(100);//不可修改
            }
        }
问:下面程序的运行结果是什么?为什么?
        class Info implements Comparable {
            public String name;
            public int age;

            public Info(String name, int age) {
                this.name = name;
                this.age = age;
            }

            @Override
            public int compareTo(Info o) {
                return o.name.compareTo(this.name);
            }

            @Override
            public boolean equals(Object obj) {
                return ((Info) obj).age == this.age;
            }
        }
        public class Demo {
            public static void main(String[] args) {
                List list = new ArrayList();
                list.add(new Info("珠海", 0756));
                list.add(new Info("小渔村", 0756));

                Collections.sort(list);
                Info info = new Info("小渔村", 0756);

                int index1 = list.indexOf(info);
                int index2 = Collections.binarySearch(list, info);
                System.out.println("index1=" + index1 + ", index2=" + index2);
            }
        }

答:这段代码的运行结果为 index1=0, index2=1。
因为集合中的元素必须做到 compareTo 与 equals 方法结果同步,由于 equals 判断的是元素是否相等,binarySearch 判断的是元素在排序中的位置是否相等,因为 indexof 是通过 equals 方法进行判断的,而 Collections.binarySearch 方法是依据 compareTo 方法进行判断的,所以结果不同。

你可能感兴趣的:(Java 集合工具类)