一.集合的继承体系

                                                                                                      

二.集合与数组的区别

数组:数组长度固定;数组是相同数据类型的集合;数组既可以存放基本数据类型,也可以存放引用数据类型。

集合:集合数组长度不固定;集合可以存放不同数据类型的数;集合只能存放引用数据类型。

三.Collection的继承接口与实现类

1.概述

Collection是集合的最顶层,他是一个接口,List与Set继承于他。

List集合存放的都是有序(有序是指存放有序,并不是会在集合中进行排序),数据可重复,这是和Set集合最大的区别。

Set集合存放的数据无序(存入和取出的顺序不一定一致)并且数据不可重复

2.List的实现类

List有三个实现类,分别为ArrayList,Vector,LinkedList.

ArrayList:底层是数组,查询快,删除慢,是一个线程不安全的集合。

Vector:底层是数组,查询快,删除慢,是一个线程安全的集合.

LinkedList:底层是链表,查询慢,删除快,是一个线程不安全的集合。

3.Set的实现类

Set有两个实现类,HashSet和TreeSet

HashSet:底层是哈希表,是一个不同步,线程不安全的集合。

TreeSet:底层是红黑树,是一个不同步,线程不安全的集合。他会自动对放入的数进行排序,所以放入的数需要可以排序,不然会报ClassCastExpection。

 

对于Treeset的排序有两种:

1.自然排序:需要实现comparable接口,重写compare方法

public class Student implements Comparable<Student>{
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
//自然排序
    @Override
    public int compareTo(Student o) {
        int num1=this.age-o.age;
        int num2=(num1==0)?this.name.compareTo(o.name):num1;
        return num2;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }
    

}
public class TreeSetDemo {
    public static void main(String[] args) {
        // 按年龄将学生排序,如果年龄相同就按名字排序
        TreeSet<Student> ts = new TreeSet<>();
        Student s1 = new Student("张三", 22);
        Student s2 = new Student("李四", 19);
        Student s3 = new Student("王五", 18);
        Student s4 = new Student("赵六", 20);
        Student s5 = new Student("张飞", 22);
        Student s6 = new Student("关羽", 18);
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);
        Iterator<Student> iterator = ts.iterator();
        while (iterator.hasNext()) {
            Student student = (Student) iterator.next();
            System.out.println(student);
        }
    }
}

2.比较器排序:要实现comparator接口,重写compare方法

public class Student {
    private String name;
    private int age;

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student [name=" + name + ", age=" + age + "]";
    }
    

}
public class TreeSetDemo2 {
    public static void main(String[] args) {
        // 按年龄将学生排序,如果年龄相同就按名字排序
        TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
            //比较器排序
            @Override
            public int compare(Student o1, Student o2) {
                int num1=o1.getAge()-o2.getAge();
                int num2=(num1==0)?o1.getName().compareTo(o2.getName()):num1;
                return num2;
            }
        });
        Student s1 = new Student("张三", 22);
        Student s2 = new Student("李四", 19);
        Student s3 = new Student("王五", 18);
        Student s4 = new Student("赵六", 20);
        Student s5 = new Student("张飞", 22);
        Student s6 = new Student("关羽", 18);
        ts.add(s1);
        ts.add(s2);
        ts.add(s3);
        ts.add(s4);
        ts.add(s5);
        ts.add(s6);
        Iterator<Student> iterator = ts.iterator();
        while (iterator.hasNext()) {
            Student student = (Student) iterator.next();
            System.out.println(student);
        }
    }
}

四.Map

1.Map与Collection的区别

(1)Map与Collection没有关系,两个都是各自集合的最顶层。

(2)Map是以键值对存入的,是双列的,而Collection是单列加入的。

(3)Map的key唯一,Collection的Set是唯一的

  (4)Map的数据结构作用于key,而Collection的数据结构作用于元素。

 2.Map集合的两个子类

(1)HashMap:底层是一个哈希表,不同步,线程不安全,键唯一,允许null键和null值。

(2)TreeMap:底层是一个红黑树,不同步,线程不安全,key具有唯一性且会排序(放入的数能够排序的,否则要实现comparaable接口或实现comparator接口)

3.Map集合的遍历

(1)利用Map的KeySet取得Set集合,然后对Set集合遍历,通过key值取得value

public static void main(String[] args) {
        Map<String, String> m = new HashMap<>();
        m.put("小李广", "花荣");
        m.put("及时雨", "宋江");
        m.put("黑旋风", "李逵");
        m.put("智多星", "吴用");
        Set<String> keySet = m.keySet();
        for (String s : keySet) {
            System.out.println(s + "==" + m.get(s));// 通过key值取得value
        }
    }

(2)利用entrySet,取得集合,分别获取Key和value

public static void main(String[] args) {
        Map<String, String> m = new HashMap<>();
        m.put("小李广", "花荣");
        m.put("及时雨", "宋江");
        m.put("黑旋风", "李逵");
        m.put("智多星", "吴用");
        Set<Entry<String, String>> set = m.entrySet();
        for(Entry<String,String> e:set) {
            System.out.println(e.getKey()+"=="+e.getValue());
        }
    }

五.collections类阐述

1.集合的工具类,包含对集合的多种操作的静态方法

2.与collection的区别

Collection是集合的最顶层接口,Collections是集合的工具类

3.Collections常用方法

(1)排序:sort()

public static void main(String[] args) {
    ArrayList <Integer>list=new ArrayList<>();
    list.add(1);
    list.add(4);
    list.add(3);
    list.add(8);
    list.add(2);
  //for (Integer i: list) {
  //   System.out.println(i);
  //}
    Collections.sort(list);
    for (Integer i: list) {
        System.out.println(i);
    }
}

(2)二分查找法:binarySearch()(前提:集合是有序的)

public static void main(String[] args) {
    ArrayList <Integer>list=new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(5);
    
    int a = Collections.binarySearch(list, 3);
    
        System.out.println(a);//打印3的下标

}

(3)最大值,最小值:max(),min()

public static void main(String[] args) {
    ArrayList <Integer>list=new ArrayList<>();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(5);
    
    int a = Collections.max(list);
    int b = Collections.min(list);
    
        System.out.println(a+" "+b);

}

(4)数据反转:reverse()

public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);

        Collections.reverse(list);
        for (Integer integer : list) {
            System.out.println(integer);
        }

    }

(5)随机置换:shuffle()(用于扑克)

public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);

        Collections.shuffle(list);
        for (Integer integer : list) {
            System.out.println(integer);
        }

    }

六.常见面试题

1.HashMap和Hashtable的区别。

(1)HashMap是线程不安全的集合,而Hashtable使用了Synchronized关键字,是线程安全的集合。
(2)HashMap允许null值和null键,而Hashtable不允许null值和null键。

(3)HashMap有快速失败机制,而HashTable没有。

   注:快速失败机制:一个软件或系统面对可能发生的错误的应对机制。

(4)HashMap继承自AbstractMap类,而Hashtable基于陈旧的Dictionary类。

(5)HashTable中hash数组默认大小是11,增加的方式是 old*2+1。

         HashMap中hash数组的默认大小是16,而且一定是2的指数。

 总结:有多个线程访问相同实例的可能时,就应该使用Hashtable,反之使用HashMap。非线程安全的数据结构能带来更好的性能。

               如果在将来有一种可能—你需要按顺序获得键值对的方案时,HashMap是一个很好的选择,因为有HashMap的一个子类 LinkedHashMap。所以如果你想可预测的按顺序迭代(默认按插入的顺                           序),你可以很方便用LinkedHashMap替换HashMap。反观要是使用的Hashtable就没那么简单了。同时如果有多个线程访问HashMap,Collections.synchronizedMap()可以代替,总的来说                          HashMap更灵活。

2.HahMap怎么解决哈希冲突

(1)通过链地址法(使用散列表)来链接拥有相同hash值的数据。

(2)使用2次扰动函数(hash函数)来降低哈希冲突的概率,使数据分布更加均匀。

(3)jdk1.8引入了红黑树进一步降低了遍历的复杂度,使遍历更快。

 3.ArrayList和vector的区别

共同点:

  ArrayList和Vector都实现了List接口,顶层都是collection,两个底层都是数组,数据都允许重复

区别:

(1)ArrayList是线程不安全的集合,而vector加了synchronized关键字,是线程安全的集合。如果只有一个线程访问集合,选择ArrayList,效率高;若有多个线程访问集合,选择vector,比较安全。

(2)数据增长:vector是数据满时,增长为原来的两倍,而ArrayList是数据存到一半时,便增长原容量的(0.5倍+1)个空间。