第十四章:集合

集合框架体系⭐

1.集合主要是两组:
	1):单列集合
	2):双列集合
2.Collectin 接口有两个重要的子接口 List Set ,他们的实现子类都是单列集合
3.Map 接口的实现子类 是双列集合,存放的 K-V
ArrayList arrayList = new ArrayList();
arrayList.add("jack");

HashMap hashMap = new HashMap();
hashMap.put("NO1","北京");

集合选型规则⭐

取决于业务操作特点,然后根据集合实现类特性进行选择

1)先判断存储的类型(一组对象[单列]或一组键值对[双列])
2)一组对象[单列]:Collection接口
	允许重复:List
		增删多:LinkedList[底层维护了一个双向链表]
		改查多:单线程:ArrayList[底层维护Object类型的可变数组]
    		   多线程:Vector
	不允许重复:Set
		无序:HashSet[底层是HashMap,维护了一个哈希表(数组+链表)+红黑树
		有序:LinkedHashSet(底层是LinkedHashMap,而其底层又为数组 + 双向链表						HashMap),维护数组+双向链表
3)一组键值对[双列]Map
	键无序:单线程:HashMap]
    	   多线程:Hashtable
	键有序:LinkedHashMap

Collection接口

CRUD
  • add
  • remove
  • contains
  • size
  • clear
  • isEmpty
  • addAll
  • removeAll
  • containsAll
package com.lcz.collection;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
 * @author lcz
 * @version 1.0
 * 关于:
 *      CRUD
 *      - add
 *      - remove
 *      - contains
 *      - size
 *      - clear
 *      - isEmpty
 *      - addAll
 *      - removeAll
 *      - containsAll
 */
@SuppressWarnings({"all"})
public class Collection_ {
    public static void main(String[] args) {
        List list = new ArrayList();
        list.add(1);
        list.add("sadfsa");
        list.add(new Integer(10));
        System.out.println(list.contains(1));
        list.remove(1);
        System.out.println(list.size());
        System.out.println(list);
        list.clear();
        System.out.println(list);
        System.out.println(list.isEmpty());
        List list1 = new ArrayList();
        list1.add('s');
        list1.add("sdafs");
        list.add(new Integer(100));
        list.addAll(0,list1);
        System.out.println(list);
        list.containsAll(list1);
        list.removeAll(list1);
        System.out.println(list);


    }
}
遍历集合的三种方式
Iterator(迭代器)

基本介绍:

Iterator iterator = collection.iterator();

Iterator对象称为迭代器,主要用于遍历 Collection 集合中的元素

执行原理:

增强for:简化版迭代器⭐
普通for
//遍历集合三种方式
        //(1):迭代器
        //快捷键ii
        System.out.println("===迭代器===");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            Object obj = iterator.next();
            System.out.println(obj);
        }
        //(2):增强for:底层仍调用迭代器,所以为简化版迭代器
        //快捷键I
        System.out.println("===增强for===");
        for(Object obj:list){
            System.out.println(obj);
        }
        //(3):普通for
        //快捷键fori
        System.out.println("===普通for===");
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

List接口

List接口是Collection接口的子接口
1.可重复的有序列表
2.支持索引
3.实现类:LinkedListArrayListVector

常用方法

  • add(int index,Object ele)
  • addAll(int index,Collection eles)
  • get(int index)
  • indexOf(Object obj)
  • lastIndexOf(Object obj)
  • remove(int index)
  • set(int index,Object ele)
  • subList(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的 子集合
list.set(0,90);
System.out.println(list);
System.out.println(list.get(0));
System.out.println(list.indexOf(90));
list.add("sadfsadf");
list.add('c');
list.add(1,50);
System.out.println(list);
System.out.println(list.subList(0,2));

ArrayList类⭐

介绍

由数组来实现数据存储的

底层扩容机制

ArrayList 中维护了一个数组

  • 无参构造器:初始容量为0,第一次添加,扩容至10,以后扩容,扩容至1.5倍
  • 指定大小的构造器:初始容量为指定大小,需扩容,则扩容至1.5倍

Vector类⭐

Vector 和 ArrayList 的比较

LinkedList类⭐

LinkedList 和 ArrayList 的比较

底层维护了一个双向链表

LinkedList中维护了两个属性first、last分别指向首结点和尾结点

每个结点(Node对象),里面又维护了prev、next、item三个属性

所以:LinkedList 类增删快,查询慢;

ArrayList 类查询快,增删慢;

Set接口

Set接口是Collection接口的子接口
1.不可重复的无序列表
2.不支持索引
3.实现类:HashSetLinkedHashSet

HashSet类⭐

介绍

无序集合

HashSet底层是HashMap,HashMap底层是(哈希表(数组+链表)+红黑树)

1.添加一个元素时,先获取元素的hash值,将hash值转成-->索引值
2.在数据对应索引位置添加该元素:
    若无元素,则添加;
    若有元素,依次和该链表的元素进行比较(用equals方法,可重写比较逻辑),都不相同,则加入到该链表的最后
3.不同的JDK不同,链表达到一定元素且数组达到一定元素, 会将对应的链表转化成红黑树(查较二叉搜索树快、增、删较平衡二叉树快)
底层扩容机制
1.HashSet的底层是HashMap,第一次添加时,table 数组扩容到16
2.临界值是(threshold)16 * 加载因子(loadFactor)0.75 = 12
3.如果table数组中的元素个数 达到 临界值12,就会扩容到二倍
4.新的临界值,依次类推
最佳实践(重写equals方法)

package com.lcz.collection.set.hashset;

import java.util.HashSet;
import java.util.Objects;

/**
 * @author lcz
 * @version 1.0
 * 需求:
 *      1.定义一个Employee类,包含name、age属性
 *      2.创建3个Employee对象放入HashSet中
 *      3.要求当name和age相同时,认为是相同员工,不能添加到HashSet集合中
 */
public class Exercise01 {
    public static void main(String[] args) {
        HashSet hashSet = new HashSet();
        hashSet.add(new Employee("lcz",20));
        hashSet.add(new Employee("lhc",20));
        hashSet.add(new Employee("孙悟空",1000));
        hashSet.add(new Employee("孙悟空",1000));
        System.out.println(hashSet);
    }

}
class Employee{
    private String name;
    private int age;

    public Employee(String name, int age) {
        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 "Employee{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

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

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
}

LinkedHashSet类⭐

介绍
1.有序集合
2.LinkedHashSet是HashSet的子类
3.LinkedHashSet 底层是一个 LinkedHashMap,其是HashMap的子类,底层维护了一个数组+双向链表

Map接口

CRUD:

1.put
2.remove
3.get
4.size
5.isEmpty
6.clear
7.containsKey

HashMap类⭐

介绍

无序的键值对

HashSet的底层就是它

唯一区别就是 HashMap为双列集合,多一个操作:添加元素时,如果键相同,则值替换

常用方法
获取的结果都是一个迭代器对象,可增强For循环或迭代器遍历输出
hashmap.values()
hashmap.keySet()
Map.Entry类:hashmap.entrySet()

LinkedHashMap类⭐

介绍

有序的键值对

LinkedHashSet的底层就是它

Hashtable类⭐

Hashtable 和 HashMap 的比较

Collections工具类

介绍

1.是一个操作Set、List、Map等集合的工具类
2.提供了一系列静态的方法对集合元素进行排序、查询和修改等操作

常用方法

  • reverse(List):反转List中元素的顺序
  • shuffle(List):对List集合元素进行随机排序
  • sort(List):根据元素的自然顺序对指定List集合元素按升序排序
  • sort(List,Comparator):根据指定的比较器产生的顺序进行排序
  • swap(List,i,j):将指定List集合中的 i 处元素和 j 处元素进行交换
  • Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
  • Object max(Collection,Comparator):根据比较器指定的顺序,返回给定集合最大元素
  • Object min(Collection)
  • Object min(Collection,Comparator)
  • int frequency(Collection,Object):返回指定集合中指定元素的出现次数
  • void copy(List dest,List src):将src的内容复制到dest中
  • boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换List对象的所有旧值

演示

package com.lcz.collection.collections;

import com.sun.xml.internal.ws.policy.privateutil.PolicyUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

/**
 * @author lcz
 * @version 1.0
 * 需求:
 *      Collections工具类常用方法
 */
public class Collections_ {
    public static void main(String[] args) {
//        - reverse(List):反转List中元素的顺序
        ArrayList arrayList = new ArrayList();
        arrayList.add("a");
        arrayList.add("b");
        arrayList.add("c");
        arrayList.add("d");
        System.out.println("翻转前");
        System.out.println(arrayList);
        Collections.reverse(arrayList);
        System.out.println("翻转后");
        System.out.println(arrayList);
//        - shuffle(List):对List集合元素进行随机排序
        Collections.shuffle(arrayList);
        System.out.println("随机排序");
        System.out.println(arrayList);
//        - sort(List):根据元素的自然顺序对指定List集合元素按升序排序
        //自然顺序:指按字符串大小
        Collections.sort(arrayList);
        System.out.println("自然排序升序后");
        System.out.println(arrayList);
//        - sort(List,Comparator):根据指定的比较器产生的顺序进行排序
        Collections.sort(arrayList, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length() - ((String)o2).length();
            }
        });
        System.out.println("按照字符串大小从小到大");
        System.out.println(arrayList);
//        - swap(List,int,int):将指定List集合中的 i 处元素和 j 处元素进行交换
        Collections.swap(arrayList,0,1);
        System.out.println("交换后");
        System.out.println(arrayList);
//
//        查找替换
//        - Object max(Collection):根据元素的自然顺序,返回给定集合中的最大元素
        System.out.println("自然顺序最大值");
        System.out.println(Collections.max(arrayList));
//        - Object max(Collection,Comparator):根据比较器指定的顺序,返回给定集合最大元素
        System.out.println("字符串长度大小最大值");
        System.out.println(Collections.max(arrayList, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return ((String)o1).length() - ((String)o2).length();
            }
        }));
//        - Object min(Collection)
//        - Object min(Collection,Comparator)
//        - int frequency(Collection,Object):返回指定集合中指定元素的出现次数
        System.out.println("指定元素a出现次数");
        System.out.println(Collections.frequency(arrayList,"a"));
//        - void copy(List dest,List src):将src的内容复制到dest中
        ArrayList arrayList1 = new ArrayList(10);
        //设置初始容量为10,仍报异常,因为list是在第一次添加元素时,才创建底层的数组,之前数组为null
        arrayList1.add("asdfas");
        arrayList1.add("ljil");
        Collections.copy(arrayList,arrayList1);
        System.out.println("复制后");
        System.out.println(arrayList);//可能会报异常:因为要求dest长度大于src长度,长度指元素个数
//        - boolean replaceAll(List list,Object oldVal,Object newVal):使用新值替换List对象的所有旧值
        Collections.replaceAll(arrayList,"c","lcz");
        System.out.println("替换后");
        System.out.println(arrayList);
    }
}

更多编程学习资源

编程学习公众号【程序员论周】

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐