集合体系详细介绍及用法

一.集合体系框架

二.基本介绍

1.集合总体概述

​ 集合是java中提供的一种容器,可以用来存储多个数据

长度可变;只能存储引用数据类型,即使存储了基本类型,到了集合中也会自动装箱成包装类;集合有很多方法,直接操作元素

2.分类(单列集合/双列集合)

单列集合:元素只由一部分构成

list.add("abc")

双列集合:一个元素由两部分构成,叫做键值对(key,value)

map.put(1,"zsy");

三.详细介绍

1.Collection接口

​ Collection接口是单列集合顶级接口

创建:Collection<E> 集合名 = new 实现类对象<E>()

是泛型,在这里先简单了解一下泛型的作用,后面会详细介绍,泛型是规定集合中元素的数据类型,统一类型的;泛型类型只能写引用类型,不能写基本类型,如果不写泛型,默认为Object类型

常用方法方法作用
.boolean add(E e)将给定的元素添加到当前集合中(一般调add时,不用boolean接收,因为add一定会成功)
boolean addAll(Collection<? extends E> c)将另一个集合元素添加到当前集合中 (集合合并)
void clear()清除集合中所有的元素
boolean contains(Object o)判断当前集合中是否包含指定的元素
boolean isEmpty()判断当前集合中是否有元素->判断集合是否为空
boolean remove(Object o)将指定的元素从集合中删除
int size()返回集合中的元素个数
Object[] toArray()把集合中的元素,存储到数组中

如下代码是方法使用的具体例子

public class Demo01 {
    public static void main(String[] args) {
        Collection<String> collection1 = new ArrayList<>();
        //add(E e)将给定的元素添加到当前集合中
        collection1.add("张三");
        collection1.add("李四");
        collection1.add("王五");
        collection1.add("赵六");
        collection1.add("刘七");
        collection1.add("陈八");
        System.out.println(collection1);
        //addAll(Collection<? extends E> c)将另一个集合元素添加到当前集合中 (集合合并)
        ArrayList<String> collection2 = new ArrayList<>();
        collection2.addAll(collection1);
        System.out.println(collection2);
        //void clear():清除集合中所有的元素
        collection2.clear();
        System.out.println(collection2);
        //boolean contains(Object o)  :判断当前集合中是否包含指定的元素
        boolean s = collection1.contains("赵六");
        System.out.println(s);
        //boolean isEmpty() : 判断当前集合中是否有元素->判断集合是否为空
        boolean empty = collection1.isEmpty();
        System.out.println(empty);
        //boolean remove(Object o):将指定的元素从集合中删除
        collection1.remove("陈八");
        System.out.println(collection1);
        //int size() :返回集合中的元素个数。
        int size = collection1.size();
        System.out.println(size);
        //Object[] toArray(): 把集合中的元素,存储到数组中
        Object[] arr = collection1.toArray();
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
    }
}

2.List接口

List接口是Collection接口的子接口

2.1ArrayList集合

创建:ArrayList<泛型> 集合名 = new ArrayList<>()

特点

  • 元素有序
  • 元素可重复
  • 有索引
  • 线程不安全
  • 数据结构:数组
常用方法方法作用
boolean add(E e)将元素添加到集合中->尾部(add方法一定能添加成功的,所以我们不用boolean接收返回值)
void add(int index, E element)在指定索引位置上添加元素
boolean remove(Object o)删除指定的元素,删除成功为true,失败为false
E remove(int index)删除指定索引位置上的元素,返回的是被删除的那个元素
E set(int index, E element)将指定索引位置上的元素,修改成后面的element元素
E get(int index)根据索引获取元素
int size()获取集合元素个数

如下代码是方法使用的具体例子

public class Demo01 {
    public static void main(String[] args) {
        ArrayList<String> list = new ArrayList<>();
        //boolean add(E e)  -> 将元素添加到集合中->尾部(add方法一定能添加成功的,所以我们不用boolean接收返回值)
        list.add("张三");
        list.add("李四");
        list.add("王五");
        list.add("赵六");
        list.add("田七");
        System.out.println(list);
        //void add(int index, E element) ->在指定索引位置上添加元素
        list.add(0,"陈二");
        System.out.println(list);
        //boolean remove(Object o) ->删除指定的元素,删除成功为true,失败为false
        //boolean result01 = list.remove("陈二");
        //System.out.println("result01 = " + result01);
        //System.out.println("list = " + list);
        //E remove(int index) -> 删除指定索引位置上的元素,返回的是被删除的那个元素
        boolean result = list.remove("陈二");
        System.out.println("result = " + result);
        System.out.println(list);
        //E set(int index, E element) -> 将指定索引位置上的元素,修改成后面的element元素
        list.set(0,"陈二");
        System.out.println(list);
        //E get(int index) -> 根据索引获取元素
        String s = list.get(0);
        System.out.println(s);
        //int size()  -> 获取集合元素个数
        int size = list.size();
        System.out.println(size);

    }
}

2.1.1底层源码分析

ArrayList() -> 构造一个初始容量为 10 的空列表(数组)。

ArrayList(int initialCapacity) -> 构造一个具有指定初始容量的空列表。

在第一次add的时候ArrayList底层才会创建一个长度为10的空列表,ArrayList底层是数组,数组定长,数组扩容是由Arrays.copyof产生了个新数组System.arrayCopy(),每次扩容,扩容1.5倍

2.2LinkedList集合

List接口的实现类,方法和ArrayList一样

特点:

  • 元素有序
  • 有索引
  • 元素可重复
  • 线程不安全
  • 数据结构:双向链表

特有方法:大量直接操作首尾元素的方法

特有方法作用
public void addFirst(E e)将指定元素插入此列表的开头。
public void addLast(E e)将指定元素添加到此列表的结尾。
public E getFirst()返回此列表的第一个元素。
public E getLast()返回此列表的最后一个元素。
public E removeFirst()移除并返回此列表的第一个元素。
public E removeLast()移除并返回此列表的最后一个元素。
public E pop()从此列表所表示的堆栈处弹出一个元素。
public void push(E e)将元素推入此列表所表示的堆栈。
public boolean isEmpty()如果列表不包含元素,则返回true。

如下代码是特有方法使用的具体例子

public class Demo01 {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<>();
        list.add("张三");
        //public void addFirst(E e):将指定元素插入此列表的开头。
        list.addFirst("李四");
        System.out.println("list = " + list);
        //public void addLast(E e):将指定元素添加到此列表的结尾。
        list.addLast("王五");
        System.out.println("list = " + list);
        //public E getFirst():返回此列表的第一个元素。
        String first = list.getFirst();
        System.out.println("first = " + first);
        //public E getLast():返回此列表的最后一个元素。
        String last = list.getLast();
        System.out.println("last = " + last);
        //public E removeFirst():移除并返回此列表的第一个元素。
        String s = list.removeFirst();
        System.out.println("s = " + s);
        //public E removeLast():移除并返回此列表的最后一个元素。
        String s1 = list.removeLast();
        System.out.println("s1 = " + s1);
        //public E pop():从此列表所表示的堆栈处弹出一个元素。
        String pop = list.pop();
        System.out.println("pop = " + pop);
        //public void push(E e):将元素推入此列表所表示的堆栈。
        list.push("赵六");
        System.out.println("list = " + list);
        //public boolean isEmpty():如果列表不包含元素,则返回true。
        boolean empty = list.isEmpty();
        System.out.println("empty = " + empty);
    }
}

2.2.1LinkedList底层成员解释说明

1.LinkedList底层成员

transient int size = 0; 元素个数

transient Node first; 第一个节点对象

transient Node last; 最后一个节点对象

2.Node代表的是结点对象

private static class Node<E> {
        E item;//节点上的元素
        Node<E> next;//记录着下一个节点地址
        Node<E> prev;//记录着上一个节点地址

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }
2.2.2LinkedList中add方法源码分析(选看)
LinkedList<String> list = new LinkedList<>();
list.add("a");
list.add("b");    

void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
}
2.2.3LinkedList中get方法源码分析(选看)

index < (size >> 1)采用二分思想,先将index与长度size的一半比较,如果index<size/2,就只从位置0往后遍历到位置index处,而如果index>size/2,就只从位置size往前遍历到位置index处。这样可以减少一部分不必要的遍历

public E get(int index) {
    checkElementIndex(index);
    return node(index).item;
} 

Node<E> node(int index) {
    // assert isElementIndex(index);

    if (index < (size >> 1)) {
        Node<E> x = first;
        for (int i = 0; i < index; i++)
            x = x.next;
        return x;
    } else {
        Node<E> x = last;
        for (int i = size - 1; i > index; i--)
            x = x.prev;
        return x;
    }
}

2.3Vector集合

Vector集合是List接口的实现类,从jdk1.0版本就有,到了jdk1.2时变成了List接口的实现类

特点:

  • 有序
  • 有索引
  • 元素可重复
  • 线程安全(效率不高)
  • 数据结构:数组

无参构造创建Vector,底层数组初始容量为10,超过了10,自动扩容,扩2倍

3.Set接口

Set接口是Collection接口的子接口

Set接口并没有对Collection接口从方法上进行任何的扩

Set集合功能的实现,底层都是依靠Map集合去实现的

3.1HashSet集合的介绍和使用

HashSet是Set接口的一个实现类

特点:

  • 元素唯一

  • 无序(存的顺序和取的顺序不一样)

  • 无索引

  • 线程不安全

  • 数据结构:哈希表

    a.jdk8之前:哈希表 = 数组+链表
    b.jdk8之后:哈希表 = 数组+链表+红黑树

加入红黑树目的:查询快好操作

方法和Collection一样

3.1.1HashSet的存储去重复的过程

1.先比较元素哈希值,再比较元素内容
2.如果哈希值不一样,内容肯定不一样,存
3.如果哈希值一样,再比较内容
如果哈希值一样,内容不一样,存
如果哈希值一样,内容也一样,去重复,后面的覆盖前面的

3.1.2HashSet存储自定义类型如何去重复

自定义对象中重写hashCode和equals方法
让set集合获取对象属性的哈希值,以及属性的内容进行比较

3.2LinkedHashSet的介绍以及使用

LinkedHashSet是Set接口的一个实现类

特点:

  • 元素唯一
  • 有序
  • 无索引
  • 线程不安全
  • 数据结构:哈希表+链表

方法和Collection一样

3.3补充:哈希值

哈希值:计算机计算出来一个十进制数,可以看做是对象的地址值

获取:调用Object中的hashCode方法

如果哈希值一样,内容有可能不一样

如果哈希值不一样,内容一定不一样

如果一个对象中重写了hashCode方法,获取的就是对象内容的哈希值了

字符串的哈希值时如何算出来的
String s = "abc"
char[] value = {'a','b','c'}
public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

第一次循环:
h = 31h+val[0] -> 31 0 + 97 = 97
第二次循环:
h = 31
h+val[1] -> 31
97+98 = 3105
第三次循环:
h = 31h+val[2] -> 313105+99 = 96354

31是一个质数,用31可以尽可能地降低内容不一样,哈希值一样的情况

3.3TreeSet集合

TreeSet 是 Set的实现类

特点:

  • 对元素进行排序
  • 元素唯一
  • 无索引
  • 线程不安全
  • 数据结构:红黑树

使用:和HashSet一样

构造:

TreeSet()-> 构造一个新的空 set,该 set 根据其元素的自然顺序进行排序

4.Map集合

Map集合是双列集合顶级接口

key和value形式,键值对形式

key唯一,但是value可以重复

map.put("张三","李四");
map.put("王五","赵六");
map.put("张三","李四1"); -> 最后李四1会覆盖涛哥

4.1HashMap的介绍和使用

HashMap是Map的实现类

特点:

  • key唯一,不能重复
  • 无序
  • 无索引
  • 线程不安全
  • 可以存储null键null值
  • 数据结构:哈希表
常用方法作用
V put(K key, V value)添加元素
V remove(Object key)根据key删除键值对,返回的是被删除的value
V get(Object key)根据key获取value
boolean containsKey(Object key)判断集合中是否包含指定的key
Collection values()获取结合中所有的value,转存到Collection集合中
Set keySet()将Map中的key获取出来,转存到Set集合中
Set<Map.Entry<K,V>> entrySet()获取Map集合中的键值对,转存到Set集合中

Map的key保证唯一和HashSet保证唯一的过程一样

4.2LinkedHashMap的介绍和使用

LinkedHashMap extends HashMap

特点:

  • key唯一,不能重复
  • 有序
  • 无索引
  • 线程不安全
  • 可以存储null键null值
  • 数据结构:哈希表+链表

使用:和HashMap一样

4.3HashMap的两种遍历方式

4.3.1获取key,根据key再获取value

Set keySet()->将Map中的key获取出来,转存到Set集合中

public class Demo01 {
    public static void main(String[] args) {
        HashMap<String, String> hashmap = new HashMap<>();
        hashmap.put("张三","李四");
        hashmap.put("王五","赵六");
        Set<String> set = hashmap.keySet();
        for (String s : set) {
            String value = hashmap.get(s);
            System.out.println("value = " + value);
        }
    }
}
4.3.2同时获取key和value

Set<Map.Entry<K,V>> entrySet()->获取Map集合中的键值对对象,转存到Set集合中

public class Demo02 {
    public static void main(String[] args) {
        HashMap<String, String> hashmap = new HashMap<>();
        hashmap.put("张三","李四");
        hashmap.put("王五","赵六");
        Set<Map.Entry<String, String>> set = hashmap.entrySet();
        for (Map.Entry<String, String> s : set) {
            String key = s.getKey();
            String value = s.getValue();
            System.out.println(key+"..."+value);
        }

    }
}

4.4HashMap存储自定义对象如何保证key唯一

key必须重写hashCode和equals方法,比较key内容的哈希值以及key的内容

4.5TreeMap

TreeMap是Map的实现类

特点:

  • 可以对key进行排序
  • key唯一,value可重复
  • 无索引
  • 线程不安全
  • 数据结构:红黑树

构造:
TreeMap() -> 对key进行自然排序
TreeMap(Comparator<? super K> comparator) -> 对key进行指定顺序排序

TreeMap<Person, String> treeMap1 = new TreeMap<>(new Comparator<Person>() {
            @Override
            public int compare(Person o1, Person o2) {
                return o2.getAge()-o1.getAge();
            }

4.6Hashtable

Hashtable是Map集合的实现类,从jdk1.0版本就有,到了jdk1.2时变成了Map的实现类

特点:

  • key唯一,value可重复
  • 无序
  • 无索引
  • 线程安全
  • 数据结构:哈希表
  • 不能存储null键null值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值