目录

  • 一、什么是集合
  • 二、Collection体系集合
  • 2.1 Collection父接口
  • 2.2 List实现类
  • 2.2.1 ArrayList
  • 2.2.2 LinkedList
  • 2.2.3 不同结构的实现方式
  • 2.3 Set子接口
  • 2.4 Set的实现类
  • 3.1.1 HashSet
  • 3.1.2 TreeSet
  • 三、Map集合
  • 3.1 Map父接口
  • 3.2 Map集合的实现类
  • 3.2.1 HashMap
  • 3.2.2 TreeMap
  • 四、Collections工具类


一、什么是集合

  • 概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
  • 和数组的区别:
  • 数组长度固定,集合长度不固定。
  • 数组可以存储基本类型和引用类型,而集合只能存储引用类型。
  • 位置:java.util.*;

集合有两个基本接口:CollectionMap。下面对这两个接口进行分析。

二、Collection体系集合

JAVa代码集合框架 java集合框架总结_java集合框架

2.1 Collection父接口

  • 特点:代表一组任意类型的对象,无序、无下标、不能重复。
  • 方法:
  • boolean add(Object obj) //添加一个对象
  • boolean addAll(Collection c) //将一个集合中的所有对象添加到此集合中
  • void clear() //清空此集合中的所有对象
  • boolean contains(Object o) //检查此集合中是否包含o对象
  • boolean equals(Object o) //比较此集合中是否与指定对象相等。
  • boolean isEmply() //判断此集合是否为空
  • boolean remove(Object o) //在此集合中移除o对象
  • int size() //返回此集合中的元素个数
  • Object[] toArray() //将此集合转换为数组
    使用
/**
 * Collection接口的使用
 * @author: Radish
 * @date: 2020-10-04 15:40
 */
public class collection {
    public static void main(String[] args) {
        //1 创建一个集合
        Collection collection = new ArrayList();
        //2 往集合中添加元素
        collection.add("苹果");
        collection.add("香蕉");
        collection.add("葡萄");
        System.out.println("个数:"+collection.size());
        System.out.println(collection);
        //3 删除元素
//        collection.remove("苹果");
//        collection.clear();

        //4 遍历
        //foreach
        for (Object o : collection) {
            System.out.println(o);
        }
        //使用迭代器
        //hashNext();
        //next();
        //remove();
        Iterator it = collection.iterator();
        while (it.hasNext()) {
            String s = (String) it.next();
            System.out.println(s);
//            collection.remove(s);  ConcurrentModificationException并发修改异常,不可同时使用
            it.remove();
        }
        System.out.println(collection);

        //5 判断
        System.out.println(collection.contains("苹果"));
        System.out.println(collection.isEmpty());
    }
}

2.2 List实现类

  • ArrayList
  • 数组结构实现,查询快、增删慢;
  • JDK1.2版本,运行效率快、线程不安全。
  • Vector:
  • 数组结构实现,查询快、增删慢;
  • JDK1.0版本,运行效率慢,线程安全。
  • LinkedList
  • 链表结构实现,增删快,查询慢。

List子接口的使用

/**
 * List子接口的使用
 * 特点:1 有序有下标  2 可重复
 */
public class Demo3 {
    public static void main(String[] args) {
        //先创建集合对象
        List list = new ArrayList<>();

        list.add("苹果");
        list.add("小米");
        list.add(0,"华为");
        System.out.println(list);
        
//        list.remove(1);

        //遍历
        //1、使用for遍历
        for (int i = 0; i < list.size();i++) {
            System.out.println(list.get(i));
        }
        //2、foreach
        for (Object o : list) {
            System.out.println(o);
        }
        //3、迭代器
        Iterator it = list.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
        //4、列表迭代器,和Iterator的区别:ListIterator可以向前或向后遍历,添加、删除、修改元素
        ListIterator listIterator = list.listIterator();
        System.out.println("-------使用列表迭代器从前往后--------");
        while (listIterator.hasNext()) {
            System.out.println(listIterator.nextIndex()+":"+listIterator.next());
        }
        //从后往前
        System.out.println("-------使用列表迭代器从后往前--------");
        while (listIterator.hasPrevious()) {
            System.out.println(listIterator.previousIndex()+":"+listIterator.previous());
        }

        //判断 一样
        //获取位置
        System.out.println(list.indexOf("华为"));
    }
}

JAVa代码集合框架 java集合框架总结_迭代器_02


注意:集合中只能放入引用类型,如果在集合中放入基本类型,它会自动装箱,变成一个包装类

2.2.1 ArrayList

使用

/**
 * ArrayList的使用
 */
public class Demo5 {
    public static void main(String[] args) {
        //扩容原来的1.5倍
        ArrayList arrayList = new ArrayList<>();
        Student s1 = new Student("郭富城","21");
        Student s2 = new Student("张国荣","23");
        Student s3 = new Student("刘德华","24");
        arrayList.add(s1);
        arrayList.add(s2);
        arrayList.add(s3);
        System.out.println("元素个数"+arrayList.size());
        System.out.println(arrayList);

        arrayList.remove(new Student("刘德华","24"));  //调用equals方法比较,重写后可用
        System.out.println(arrayList);

        System.out.println("----------使用迭代器---------");
        Iterator it = arrayList.iterator();
        while (it.hasNext()) {
            Student student = (Student) it.next();
            System.out.println(student);
        }
        System.out.println("----------使用列表迭代器(正序)---------");
        ListIterator listIterator = arrayList.listIterator();
        while (listIterator.hasNext()){
            Student next = (Student) listIterator.next();
            System.out.println(next);
        }
        System.out.println("----------使用列表迭代器(逆序)---------");
        while (listIterator.hasPrevious()) {
            Student stu = (Student) listIterator.previous();
            System.out.println(stu);
        }

        //判断
        System.out.println(arrayList.contains(new Student("张国荣", "23")));
        System.out.println(arrayList.isEmpty());

        //查找
        System.out.println(arrayList.indexOf(new Student("张国荣","23")));
    }
}

注意:代码中arrayList.contains(new Student("张国荣", "23"))的contains方法和indexof方法以及remove方法本质上是equals方法进行比较,因此需重写equals方法才能实现

@Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(name, student.name) &&
                Objects.equals(age, student.age);
    }

源码分析

JAVa代码集合框架 java集合框架总结_java集合框架_03


JAVa代码集合框架 java集合框架总结_JAVa代码集合框架_04

2.2.2 LinkedList

使用

public class Demo2 {
    public static void main(String[] args) {
        LinkedList linkedList = new LinkedList<>();
        Student s1 = new Student("郭富城","21");
        Student s2 = new Student("张国荣","23");
        Student s3 = new Student("刘德华","24");
        linkedList.add(s1);
        linkedList.add(s2);
        linkedList.add(s3);
        System.out.println("元素个数:"+linkedList.size());
        System.out.println(linkedList.toString());

        linkedList.remove(new Student("张国荣","23"));
        System.out.println(linkedList);
    }
}

注意:代码中linkedList.remove(new Student("张国荣","23"))的remove方法和indexof方法以及contains方法本质上是equals方法进行比较,因此需重写equals方法才能实现

源码分析

JAVa代码集合框架 java集合框架总结_System_05


JAVa代码集合框架 java集合框架总结_java集合框架_06


JAVa代码集合框架 java集合框架总结_java集合框架_07

2.2.3 不同结构的实现方式

JAVa代码集合框架 java集合框架总结_JAVa代码集合框架_08

2.3 Set子接口

  • 特点:无序、无下标、元素不可重复
  • 方法:全部继承自Collection中的方法

Set接口的使用

/**
 * 测试Set接口的使用
 * 特点:无序,无下标    不能重复
 * @author: Radish
 * @date: 2020-10-05 13:59
 */
public class Demo1 {
    public static void main(String[] args) {
        //创建集合
        Set<String> set = new HashSet<>();
        set.add("小米");
        set.add("华为");
        set.add("苹果");
        System.out.println(set);

        //删除
        set.remove("小米");
        System.out.println(set);

        //遍历
        System.out.println("--------foreach---------");
        for (String s : set) {
            System.out.println(s);
        }
        System.out.println("--------使用迭代器---------");
        Iterator<String> it = set.iterator();
        while (it.hasNext()) {
            String next = it.next();
            System.out.println(next);
        }
    }
}

2.4 Set的实现类

  • HashSet
  • 基于HashCode实现元素不重复
  • 当存入元素的哈希码相同时,会调用equals进行确认,如果结果为true,则拒绝后者存入。
  • TreeSet:
  • 基于排列顺序实现元素不重复
  • 实现了SortedSet接口,对集合元素自动排序
  • 元素对象的类型必须实现Comparable接口,指定排序规则
  • 通过CompareTo方法确定是否为重复元素。

3.1.1 HashSet

使用

/**
 * HashSet集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * @author: Radish
 * @date: 2020-10-05 14:15
 */
public class Demo2 {
    public static void main(String[] args) {
        HashSet<String> hashSet = new HashSet<String>();
        hashSet.add("刘德华");
        hashSet.add("周星驰");
        hashSet.add("周润发");
        hashSet.add("成龙");
        System.out.println(hashSet);

        hashSet.remove("成龙");
        System.out.println(hashSet);

        for (String s : hashSet) {
            System.out.println(s);
        }

        Iterator<String> it = hashSet.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }

        System.out.println(hashSet.contains("成龙"));
        System.out.println(hashSet.isEmpty());
    }
}
/**
 * HashSet的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 存储过程:
 * (1)根据hashCode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步。
 * (2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
 * @author: Radish
 * @date: 2020-10-05 14:26
 */
public class Demo3 {
    public static void main(String[] args) {
        HashSet<Person> hashSet = new HashSet<Person>();
        Person p1 = new Person("刘德华",22);
        Person p2 = new Person("成龙",24);
        Person p3 = new Person("周润发",23);
        Person p4 = new Person("林志玲",21);
        hashSet.add(p1);
        hashSet.add(p2);
        hashSet.add(p3);
        hashSet.add(p4);
        hashSet.add(new Person("刘德华",22));
        System.out.println(hashSet);

        System.out.println("删除后:");
        hashSet.remove(new Person("刘德华",22));
        System.out.println(hashSet);

        System.out.println("-------------------");
        for (Person person : hashSet) {
            System.out.println(person);
        }
        System.out.println("-------------------");
        Iterator<Person> iterator = hashSet.iterator();
        while (iterator.hasNext()){
            Person next = iterator.next();
            System.out.println(next);
        }

        System.out.println(hashSet.contains(new Person("成龙", 24)));
        System.out.println(hashSet.isEmpty());
    }
}

注意:HashSet的存储过程:
(1)根据hashCode计算保存的位置,如果此位置为空,则直接保存,如果不为空执行第二步。
(2)再执行equals方法,如果equals方法为true,则认为是重复,否则,形成链表
因此,要想实现hashSet.add(new Person("刘德华",22));不加入重复对象,需重写hashCode()和equals()

3.1.2 TreeSet

/**
 * TreeSet的使用
 * 存储结构:红黑树
 * @author: Radish
 * @date: 2020-10-05 15:08
 */
public class Demo4 {
    public static void main(String[] args) {
        TreeSet<String> treeSet = new TreeSet<String>();
        treeSet.add("sdf");
        treeSet.add("asdf");
        treeSet.add("rtew");
        treeSet.add("qrs");
        System.out.println(treeSet);

        treeSet.remove("sdf");
        System.out.println(treeSet);

        System.out.println("--------------");
        for (String s : treeSet) {
            System.out.println(s);
        }
        System.out.println("--------------");
        Iterator<String> it = treeSet.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }

        treeSet.contains("sdf");
    }
}

自动排序

JAVa代码集合框架 java集合框架总结_java集合框架_09

/**
 * 使用TreeSet保存数据
 * 存储结构:红黑树
 * 要求:元素必须实现Comparable接口
 * @author: Radish
 * @date: 2020-10-05 15:15
 */
public class Demo5 {
    public static void main(String[] args) {
        TreeSet<Person> treeSet = new TreeSet<Person>();
        Person p1 = new Person("dfs",23);
        Person p2 = new Person("hello",21);
        Person p3 = new Person("good",22);
        Person p4 = new Person("cat",24);
        treeSet.add(p1);
        treeSet.add(p2);
        treeSet.add(p3);
        treeSet.add(p4);
        System.out.println(treeSet);

        treeSet.remove(new Person("cat",24));
        System.out.println(treeSet);

        System.out.println("--------------");
        for (Person person : treeSet) {
            System.out.println(person);
        }
        System.out.println("--------------");
        Iterator<Person> it = treeSet.iterator();
        while (it.hasNext()) {
            System.out.println(it.next());
        }
    }
}

注意:TreeSet存入的元素必须实现Comparable接口,若没有实现,则会报错

public class Person implements Comparable<Person>

也可以使用Comparator比较器实现定制比较

/**
 * TreeSet集合的使用
 * Comparator:实现定制比较(比较器)
 * Comparable:可比较的
 * @author: Radish
 * @date: 2020-10-05 16:48
 */
public class Demo6 {
    public static void main(String[] args) {
        TreeSet<Person> treeSet = new TreeSet<>(new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                int n1 = o1.getAge() - o2.getAge();
                int n2 = o1.getName().compareTo(o2.getName());
                return n1 == 0? n2:n1;
            }
        });

        Person p1 = new Person("dsf",23);
        Person p2 = new Person("asg",21);
        Person p3 = new Person("wer",23);
        Person p4 = new Person("zcv",24);

        treeSet.add(p1);
        treeSet.add(p2);
        treeSet.add(p3);
        treeSet.add(p4);

        System.out.println(treeSet);
    }
}

三、Map集合

JAVa代码集合框架 java集合框架总结_迭代器_10

3.1 Map父接口

  • 特点:存储一对数据(Key-Value),无序、无下标,键不可重复,值可以重复。
  • 方法:
  • V put(K key, V value) //将对象存入到集合中,关联键值。key重复则覆盖原值。
  • Object get(Object key) //根据键获取对应的值
  • Set\<K\> //返回所有的key
  • Collection\<V\> values() //返回包含所有值的Collection集合
  • Set\<Map.Entry\<K,V>> //键值匹配的Set的集合

Map接口的使用

/**
 * Map接口的使用
 * 特点:(1)存储键值对 (2)键不能重复,值可以重复 (3)无序
 * @author: Radish
 * @date: 2020-10-05 17:07
 */
public class Demo1 {
    public static void main(String[] args) {
        //创建Map集合
        Map<String, String> map = new HashMap<String,String>();

        map.put("cn","中国");
        map.put("usa","美国");
        map.put("uk","英国");
        map.put("usa","meiguo");

        System.out.println(map);

        //删除
        map.remove("usa");
        System.out.println(map);

        //遍历
        //使用keySet();
        System.out.println("--------keySet()----------");
//        Set<String> keySet = map.keySet();
        for (String s : map.keySet()) {
            System.out.println(s+":"+map.get(s));
        }
        //使用entrySet()方法
        System.out.println("--------entrySet()-------");
        Set<Map.Entry<String, String>> entrySet = map.entrySet();
        for (Map.Entry<String, String> entry : entrySet) {
            System.out.println(entry.getKey()+"-----"+entry.getValue());
        }

        //判断
        System.out.println(map.containsKey("cn"));
        System.out.println(map.containsValue("美国"));
    }
}

3.2 Map集合的实现类

  • HashMap
  • JDK1.2版本,线程不安全,运行效率快;允许用null作为key或是value.
  • HashTable:
  • JDK1.0版本,线程安全,运行效率慢;不允许null作为key或是value
  • Properties:
  • Hashtable的子类,要求key和value都是String。通常用于配置文件的读取。
  • TreeMap:
  • 实现了SortedMap接口(是Map的子接口),可以对key自动排序。

3.2.1 HashMap

使用

/**
 * HashMap集合的使用
 * 存储结构:哈希表(数组+链表+红黑树)
 * 使用key的hashcode和equals作为重复依据
 * @author: Radish
 * @date: 2020-10-05 19:38
 */
public class Demo2{
    public static void main(String[] args) {
        HashMap<Student, String> hashMap = new HashMap<Student,String>();
        //刚创建HashMap时没有添加元素 table=null  size=0 目的是节省空间

        Student s1 = new Student("牛顿","1234");
        Student s2 = new Student("刘邦","124");
        Student s3 = new Student("项羽","123");

        hashMap.put(s1, "上海");
        hashMap.put(s2, "深圳");
        hashMap.put(s3, "广州");
        hashMap.put(new Student("牛顿","1234"),"北京");

        System.out.println(hashMap);

        hashMap.remove(s1);
        System.out.println(hashMap);

        System.out.println("-------keySet-------");
        for (Student student : hashMap.keySet()) {
            System.out.println(student+"======"+hashMap.get(student));
        }
        System.out.println("-------entrySet-------");
        for (Map.Entry<Student, String> entry : hashMap.entrySet()) {
            System.out.println(entry.getKey()+"======"+entry.getValue());
        }

        System.out.println(hashMap.containsKey(s2));
        System.out.println(hashMap.containsValue("广州"));
        System.out.println(hashMap.isEmpty());
    }
}

源码分析

static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; //hashMap初始容量大小
static final int MAXIMUM_CAPACITY = 1 << 30;//hashMap的数组最大容量
static final float DEFAULT_LOAD_FACTOR = 0.75f;//默认加载因子
static final int TREEIFY_THRESHOLD = 8;//jdk1.8 当链表长度大于8时,调整成红黑树
static final int UNTREEIFY_THRESHOLD = 6;//jdk1.8 当链表长度小于6时,调整成链表
static final int MIN_TREEIFY_CAPACITY = 64;//jdk1.8 当链表长度大于8时,并且集合元素个数大于等于64时,调整成红黑树
transient Node<K,V>[] table;//哈希表中的数组
size;//元素个数

总结:

(1)当HashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16
(2)当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数
(3)jdk1.8 当每个链表长度大于8,并且数组元素个数大于等于64时,会调整为红黑树,目的是为了提高效率
(4)jdk1.8 当链表长度小于6时,调整成链表
(5)jdk1.8以前,链表是头插入,jdk1.8以后是尾插入

3.2.2 TreeMap

使用

/**
 * TreeMap的使用
 * 存储结构:红黑树
 * @author: Radish
 * @date: 2020-10-05 21:56
 */
public class Demo3 {
    public static void main(String[] args) {
        TreeMap<Student, String> treeMap = new TreeMap<Student, String>(new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                return o1.getSno().compareTo(o2.getSno());
            }
        });

        Student s1 = new Student("sfd","214");
        Student s2 = new Student("xcvb","124");
        Student s3 = new Student("erwt","456");
        Student s4 = new Student("gfd","4532");
        Student s5 = new Student("vcxb","346");

        treeMap.put(s1, "广州");
        treeMap.put(s2, "深圳");
        treeMap.put(s3, "上海");
        treeMap.put(s4, "东莞");
        treeMap.put(s5, "惠州");

        System.out.println(treeMap);

        //删除
        treeMap.remove(s1);
        System.out.println(treeMap);

        System.out.println("-------keySet--------");
        //遍历
        for (Student student : treeMap.keySet()) {
            System.out.println(student+"==========="+treeMap.get(student));
        }

        System.out.println("-------entrySet--------");
        for (Map.Entry<Student, String> entry : treeMap.entrySet()) {
            System.out.println(entry.getKey()+"==============="+entry.getValue());
        }

        System.out.println(treeMap.containsKey(s2));
        System.out.println(treeMap.containsValue("上海"));
    }
}

四、Collections工具类

  • 概念:集合工具类,定义了除了存取以外的集合常用方法
  • 方法:

使用

/**
 * 演示Collections工具类的使用
 * @author: Radish
 * @date: 2020-10-05 22:11
 */
public class Demo4 {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(123);
        list.add(23);
        list.add(43);
        list.add(25);
        list.add(2);
        System.out.println("=============排序前=============");
        System.out.println(list);
        //sort排序
        Collections.sort(list, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        System.out.println("=============排序后=============");
        System.out.println(list);

        //binarySearch 二分查找
        int i = Collections.binarySearch(list, 2235);
        System.out.println(i);

        //copy复制
        ArrayList<Integer> list2 = new ArrayList<>();
        for (int k = 0; k < list.size(); k++) {
            list2.add(0);
        }
        Collections.copy(list2, list);
        System.out.println(list2);

        //reverse反转
        Collections.reverse(list);
        System.out.println("反转之后"+list);

        //shuffle 打乱
        Collections.shuffle(list);
        System.out.println("打乱之后"+list);

        //补充:list转成数组
        System.out.println("-------list转成数组-------");
        Integer[] array = list.toArray(new Integer[0]);
        System.out.println(array.length);
        System.out.println(Arrays.toString(array));

        //数组转成集合
        System.out.println("-------数组转成集合-------");
        String[] names = {"张三", "李四", "王五"};
        //这个集合是一个受限的集合,不能增加和删除
        List<String> list3 = Arrays.asList(names);
        System.out.println(list3);
        //把基本类型数组转成集合时,需要修改为包装类
        Integer[] nums= {100,200,300,400,500};
        List<Integer> list4 = Arrays.asList(nums);
        System.out.println(list4);

    }
}