文章目录

  • 集合
  • 集合概述
  • 集合体系核心框架图
  • 分类
  • 单列集合
  • 双列集合
  • 集合和数组的区别
  • Collection
  • 主要方法
  • List
  • ArrayList
  • Vector
  • Stack
  • LinkedList
  • Collection常用遍历方法
  • Iterator遍历集合
  • foreach遍历集合
  • forEach遍历
  • Set
  • HashSet
  • TreeSet
  • Map
  • HashMap
  • TreeMap
  • Map常用遍历方法
  • Iterator遍历集合
  • foreach遍历集合
  • forEach遍历集合
  • 集合特征图
  • 小结


集合

集合概述

1、Java集合就是一个容器,用来存储Java对象的引用(通常称为对象)

2、这些集合位于java.util包中

集合体系核心框架图

java 集合常见问题 java 常用集合_集合

分类

单列集合

Collection:单列集合的根接口,用来存储一系列符合某种规则的元素,Collection有两个重要的接口,分别是List和Set

双列集合

Map:双列集合的根接口,用来存储具有键(Key)、值(Value)映射关系的元素,Map有两个重要的接口,分别是HashMap和TreeMap

集合和数组的区别

数组

集合

长度区别

长度固定,不能增大或减小

长度可变,可以根据元素个数增大

数据类型

基本类型、引用类型

引用类型

内容区别

只能存储同一种数据类型

可以存储多种类型(一般为同一种)

Collection

Collection接口是一个顶层接口,主要定义集合的约定

主要方法

方法

功能

boolean add(Object obj)

向集合中添加一个元素obj

boolean addAll(Collection c)

将指定集合c中的所有元素添加到该集合中

boolean remove(Object obj)

删除该集合中指定的元素

boolean removeAll(Collection c)

删除集合中包含指定集合c中的所有元素

boolean isEmpty()

判断集合是否为空

boolean contains(Object obj)

判断集合中是否包含某个元素

boolean containsAll(Collection c)

判断集合中是否包含指定的集合c中所有元素

void clear()

清空集合

int size()

返回集合中元素个数

List

1、List接口也算是一个顶层接口,继承了Collection接口,同时也是ArrayList,LinkedList等集合的父类

2、集合中元素有序,可以出现重复元素,可以通过索引访问元素

常用方法

方法

功能

void add(int index,Object obj)

将元素obj插入到List指定索引位置

boolean addAll(int index,Collection c)

将集合c中所有元素插入到List指定的索引位置

Object get(int index)

返回集合索引位置index的值

Object remove(int index)

删除索引index的元素

Object set(int index,Object obj)

将索引index位置的值替换为obj,返回替换前的值

int indexOf(Object obj)

返回obj在集合中首次出现的位置

int lastIndexOf(Object obj)

返回obj在集合中最后一次出现的位置

Object[] toArray()

将集合元素转化为数组

void sort()

将集合按指定比较规则排序

ArrayList

ArrayList是实现了List接口的可扩容数组(动态数组),它的内部封装了一个长度可变的数组对象

由于它的内部是数组,所以进行增删操作效率很低,但是数组结构允许通过索引来访问元素,所以ArrayList集合在遍历和查找时十分高效

但是有一点,ArrayList不是线程安全的容器,如果多个线程中至少两个线程修改了ArrayList的结构的话,就会导致线程安全问题

Vector

Vector和ArrayList一样,都是基于数组实现,只不过Vector是一个线程安全的容器,它的内部每个方法都上了锁,避免多线程引起的安全性问题,但是这种同步方式需要的开销比较大,所以访问元素的效率远远低于ArrayList

扩容上,Vector扩容后数组长度为原来的两倍,而ArrayList扩容每次增加50%,也就是原来的1.5倍

Stack

Stack继承了Vector类,提供了栈的常用方法:

方法

功能

Object push(Object obj)

将元素推到栈顶

Object pop()

移出并返回栈顶元素

Object peek()

返回栈顶元素但不删除

boolean empty()

判断栈是否为空

int search(Object obj)

返回元素在栈中的位置,栈顶为1,不存在返回-1

LinkedList

LinkedList内部封装了一个双向链表,使用两个Node类型的first和last维护双向链表

所有元素通过链表联系起来,因此在做增删操作时,会有很高的效率

LinkedList除了继承Collection和List接口并实现集合的方法外,还提供了很多特殊的方法:

如下:

方法

功能

void add(int index,E element)

在集合中指定位置添加元素obj

void addFirst(Object obj)

在集合开头插入obj

void addLast(Object obj)

在集合结尾插入obj

Object getFirst()

返回第一个元素

Object getLast()

返回最后一个元素

Object removeFirst()

移出并返回第一个元素

Object removeLast()

移出并返回最后一个元素

boolean offer(Object obj)

将指定元素添加到集合的结尾

boolean offerFirst(Object obj)

将指定元素添加到集合的开头

boolean offerLast(Object obj)

将指定元素添加到集合的结尾

Object peek()

返回集合第一个元素

Object peekFirst()

返回集合第一个元素

Object peekLast()

返回集合最后一个元素

Object poll()

移出并返回集合的第一个元素

Object pollFirst()

移出并返回集合的第一个元素

Object pollLast()

移出并返回集合的最后一个元素

void push(Object obj)

将指定元素添加到集合开头

Object pop()

移出并返回第一个元素

Collection常用遍历方法

Iterator遍历集合

Iterator主要用于迭代访问(遍历),所以Iterator对象又称为迭代器

举例如下:

import java.util.ArrayList;
import java.util.Iterator;

public class Main {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            Object obj = iterator.next();
            System.out.println(obj);
        }
    }
}

或者简单些:

for(Iterator iterator = list.iterator();iterator.hasNext();){
    System.out.println(iterator.next());
}

说明:

1、遍历元素时,首先通过调用ArrayList集合的iterator()方法获得迭代器对象,然后使用hasNext()方法判断集合中是否存在下一个元素,如果存在,则调用next()方法将元素取出

2、Iterator迭代器内部采用了指针的方式跟踪集合中的元素,在调用next()方法前,迭代器位于第一个元素之前,不指向任何元素,当开始调用next()方法时,迭代器会指向第一个元素并返回,当再次调用时,会指向第二个元素并返回…直到hasNext()返回false停止

foreach遍历集合

foreach循环是for循环的增强版,可以用于数组和集合,不需要知道数组/容器的长度,也不需要索引就可以自动访问

举例如下:

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        
        for (Object obj : list) {
            System.out.println(obj);
        }
    }
}

注:foreach循环虽然写起来很简单,但是也有局限性。使用foreach循环遍历集合或者数组时,只能访问,不能修改元素

forEach遍历

forEach遍历使用Lambda表达式

举例如下:

import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(3);
        list.forEach(obj-> System.out.println(obj));
    }
}

Set

1、Set接口和List接口一样继承自Collection

2、集合中元素无序,并且不会重复出现

HashSet

HashSet是Set接口的一个实现类,存储的元素不可以重复,并且元素都是无序的,允许存在null

当向HashSet集合中添加一个元素时,首先会调用该元素的hashCode()方法来获取hash值和确定元素的存储位置,如果该位置没有元素则直接添加,若有元素,则调用equals()方法让添加的元素与该位置上的元素一一比较,如果返回false,则可以添加,如果返回true,则说明有重复元素,则直接把要添加的元素丢掉

当向集合中添加元素时,通常需要重写hashCode()和equals()方法,否则可能当添加相同的对象时因为地址不同而都添加成功

TreeSet

TreeSet是Set接口的另一个实现类,内部采用的是平衡二叉树存储元素,所以TreeSet集合中没有重复的元素,并且可以对元素进行排序

TreeSet在继承Set接口的基础上新增了一些方法:

如下:

方法

功能

Object first()

返回TreeSet集合的第一个元素

Object last()

返回TreeSet集合的最后一个元素

Object lower(Object obj)

返回TreeSet集合中小于obj的最大元素,没有则返回null

Object floor(Object obj)

返回TreeSet集合中小于等于obj的最大元素,没有则返回null

Object higher(Object obj)

返回TreeSet集合中大于obj的最小元素,没有则返回null

Object ceiling(Object obj)

返回TreeSet集合中大于等于obj的最小元素,没有则返回null

Object pollFirst()

移出并返回集合的第一个元素

Object pollLast()

移出并返回集合最后一个元素

元素在添加时,会进行比较,此时自动调用compareTo()方法

TreeSet有两种排序规则:自然排序和定制排序

1、自然排序:默认情况下都是使用自然排序

2、定制排序:创建时使用Comparator进行排序

Map

Map接口是一种双列集合,使用Key-Value键值对,键值之间存在一种一对一的映射关系,一个Key只能对应一个Value,并且Key不能重复,在访问集合中的元素的时候,指定了Key,就能找到对应的Value

Map接口定义了很多方法

如下:

方法

功能

voif put(Object key,Object value)

向Map集合中添加元素

void clear()

清空整个集合

int size()

返回Map键值对个数

boolean containsKey(Object key)

返回集合中是否存在指定的key

boolean containsValue(Object value)

返回集合中是否存在指定的value

Object get(Object key)

返回指定键对应的值,如果不存在此key,返回null

Object remove(Object key)

移出并返回指定的key对应的值value

Set keySet()

以Set集合的形式返回Map集合中所有的值对象value

boolean remove(Object key,Object value)

删除Map集合中指定的键值同时匹配的元素

boolean replace(Object key,Object value)

将Map集合中指定的键key的值修改为value

Object getOrDefault(Object key,Object defaultValue)

返回Map集合中指定键对应的值,不存在则返回defaultValue

HashMap

HashMap 是一个散列表,它存储的内容是键值对(key-value)映射。

HashMap 实现了 Map 接口,根据键的 HashCode 值存储数据,具有很快的访问速度,最多允许一条记录的键为 null,不支持线程同步。

HashMap 是无序的,即不会记录插入的顺序。

HashMap 继承于AbstractMap,实现了 Map、Cloneable、java.io.Serializable 接口。

TreeMap

Map接口另一个常用类TreeMap,也是存储键值映射关系的元素,并且不能出现重复的key

TreeMap和TreeSet一样,会对存入的元素进行大小排序,也是有自然排序和定制排序两种

不同于HashMap的是,TreeMap内部是红黑树

Map常用遍历方法

Iterator遍历集合

1、第一种方式:

将所有的键key转化为Set集合,接着将Set集合转换为Iterator接口对象,然后遍历Map集合中所有的键,根据键获取对应的值

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap();
        map.put("1", 101);
        map.put("2", 102);
        map.put("3", 103);
        Iterator iterator = map.keySet().iterator();
        while (iterator.hasNext()) {
            Object key = iterator.next();
            Object value = map.get(key);
            System.out.println(key + " : " + value);
        }
    }
}

2、第二种方式:

首先调用Map对象的entrySet()方法获得存储键值的Set集合,这个集合存放的是Map.Entry类型的元素,每个Map.Entry对象代表一个键值对,然后迭代Set集合,根据键获取对应的值

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap();
        map.put("1", 101);
        map.put("2", 102);
        map.put("3", 103);

        Iterator iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            Object key = entry.getKey();
            Object value = entry.getValue();
            System.out.println(key + " : " + value);
        }
    }
}

foreach遍历集合

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap();
        map.put("1", 101);
        map.put("2", 102);
        map.put("3", 103);
        for (Object key : map.keySet()) {
            System.out.println(key + " : " + map.get(key));
        }
    }
}

forEach遍历集合

和Collection遍历集合的forEach方法一样,也是使用Lambda表达式

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> map = new HashMap();
        map.put("1", 101);
        map.put("2", 102);
        map.put("3", 103);
        map.forEach((key, value) -> System.out.println(key + " : " + value));
    }
}

集合特征图

集合

有序无序

是否随机访问

重复元素

空元素

线程安全

ArrayList

Vector

Stack

LinkedList

HashSet

TreeSet

HashMap

TreeMap

小结

本篇文章只写了集合的基础部分总结,更深的内容没有提到,若有错误请指正