Java基础之集合类

一、集合的框架

1.1、集合概述

所有的集合类和集合接口都在java.util包下。在内存中申请一块空间用来存储数据,在Java中集合就是替换掉定长的数组的一种引用数据类型。

1.2、集合与数组区别

区别集合数组
长度大小可以变,用多少空间拿多少空间。长度固定,定义长了造成内存空间的浪费
定义短了不够用。
内容能存储引用数据类型(存储的为对象的内存地址)存储基本数据类型和引用数据类型
元素可以存储不同类型数据
(一般情况下也只存储同一种类型的数据)
只能存储同一种类型成员

1.3、数组的缺点:

  1. 数组一旦初始化长度、类型就不能再改变了,只能按照初始化的数据类型和长度进行存储数据了。
  2. 数组中提供的方法比较有限,对于数据的增删改查操作不方便,并且效率也不太高。
  3. 可以存储重复的值,并且有序特点单一。

1.4、常用集合分类

在这里插入图片描述


Collection 接口的接口 对象的集合(单列集合)
├——-List 接口:元素按进入先后有序保存,可重复
│—————-├ LinkedList 接口实现类, 链表, 插入删除, 没有同步, 线程不安全
│—————-├ ArrayList 接口实现类, 数组, 随机访问, 没有同步, 线程不安全
│—————-└ Vector 接口实现类 数组, 同步, 线程安全
│ ———————-└ Stack 是Vector类的实现类
└——-Set 接口: 仅接收一次,不可重复,并做内部排序
├—————-└HashSet 使用hash表(数组)存储元素
│————————└ LinkedHashSet 链表维护元素的插入次序
└ —————-TreeSet 底层实现为二叉树,元素排好序

Map 接口 键值对的集合 (双列集合)
├———Hashtable 接口实现类, 同步, 线程安全
├———HashMap 接口实现类 ,没有同步, 线程不安全-
│—————–├ LinkedHashMap 双向链表和哈希表实现
│—————–└ WeakHashMap
├ ——–TreeMap 红黑树对所有的key进行排序
└———IdentifyHashMap

注意:

①List接口,用于存储有序的、可重复的数据(可以想象成动态的数组)

②Set接口,存储无序的、不可重复的数据(类似于高中的集合)

//Collection源码如下
public interface Collection<E> extends Iterable<E> {

1.5、Collection常用方法

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

public class CollectionExample {
    public static void main(String[] args) {
        // 创建一个ArrayList
        Collection<String> stringList = new ArrayList<>();

        // 添加元素
        stringList.add("Apple");
        stringList.add("Banana");
        stringList.add("Orange");

        // 获取集合大小
        int size = stringList.size();
        System.out.println("Size: " + size);

        // 判断集合是否为空
        boolean isEmpty = stringList.isEmpty();
        System.out.println("Is Empty: " + isEmpty);

        // 判断集合是否包含元素
        boolean containsBanana = stringList.contains("Banana");
        System.out.println("Contains Banana: " + containsBanana);

        // 删除元素
        boolean removed = stringList.remove("Orange");
        System.out.println("Removed Orange: " + removed);

        // 获取集合迭代器并遍历
        Iterator<String> iterator = stringList.iterator();
        while (iterator.hasNext()) {
            String element = iterator.next();
            System.out.println("Element: " + element);
        }

        // 添加多个元素
        Collection<String> anotherList = new ArrayList<>();
        anotherList.add("Grapes");
        anotherList.add("Pineapple");
        stringList.addAll(anotherList);

        // 转换为数组
        Object[] array = stringList.toArray();
        System.out.println("Array: " + java.util.Arrays.toString(array));

        // 清空集合
        stringList.clear();
        System.out.println("Size after clear: " + stringList.size());
    }
}

二、List集合

2.1、ArrayList

//ArrayList构造方法
public ArrayList(int initialCapacity)//构造一个具有指定初始容量的空列表。    
public ArrayList()      //默认构造一个初始容量为10的空列表。    
public ArrayList(Collection<? extends E> c)//构造一个包含指定 collection 的元素的列表

代码示例:

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

public class ArrayListExample {
    public static void main(String[] args) {
        // 创建 ArrayList
        List<String> arrayList = new ArrayList<>();

        // 添加元素
        arrayList.add("Apple");
        arrayList.add("Banana");
        arrayList.add("Orange");

        // 获取元素
        String firstElement = arrayList.get(0);
        System.out.println("First Element: " + firstElement);

        // 修改元素
        arrayList.set(1, "Grapes");

        // 删除元素
        arrayList.remove("Orange");

        // 获取 ArrayList 大小
        int size = arrayList.size();
        System.out.println("Size: " + size);

        // 判断是否包含某个元素
        boolean containsBanana = arrayList.contains("Banana");
        System.out.println("Contains Banana: " + containsBanana);

        // 遍历 ArrayList(使用增强 for 循环)
        System.out.println("Iterating using enhanced for loop:");
        for (String fruit : arrayList) {
            System.out.println(fruit);
        }

        // 遍历 ArrayList(使用迭代器)
        System.out.println("Iterating using Iterator:");
        Iterator<String> iterator = arrayList.iterator();
        while (iterator.hasNext()) {
            String fruit = iterator.next();
            System.out.println(fruit);
        }

        // 转换为数组
        Object[] array = arrayList.toArray();
        System.out.println("Array: " + java.util.Arrays.toString(array));

        // 清空 ArrayList
        arrayList.clear();

        // 判断是否为空
        boolean isEmpty = arrayList.isEmpty();
        System.out.println("Is Empty: " + isEmpty);
    }
}

2.2、LinkedList

LinkedList 是 Java 集合框架中 List 接口的另一个实现,基于链表实现。相比于 ArrayListLinkedList 在插入和删除元素的操作上更为高效,但在随机访问方面较慢。

代码示例:

import java.util.LinkedList;
import java.util.Iterator;
import java.util.List;

public class LinkedListExample {
    public static void main(String[] args) {
        // 创建 LinkedList
        List<String> linkedList = new LinkedList<>();

        // 添加元素
        linkedList.add("Apple");
        linkedList.add("Banana");
        linkedList.add("Orange");

        // 获取元素
        String firstElement = linkedList.get(0);
        System.out.println("First Element: " + firstElement);

        // 修改元素
        linkedList.set(1, "Grapes");

        // 删除元素
        linkedList.remove("Orange");

        // 获取 LinkedList 大小
        int size = linkedList.size();
        System.out.println("Size: " + size);

        // 判断是否包含某个元素
        boolean containsBanana = linkedList.contains("Banana");
        System.out.println("Contains Banana: " + containsBanana);

        // 遍历 LinkedList(使用增强 for 循环)
        System.out.println("Iterating using enhanced for loop:");
        for (String fruit : linkedList) {
            System.out.println(fruit);
        }

        // 遍历 LinkedList(使用迭代器)
        System.out.println("Iterating using Iterator:");
        Iterator<String> iterator = linkedList.iterator();
        while (iterator.hasNext()) {
            String fruit = iterator.next();
            System.out.println(fruit);
        }

        // 转换为数组
        Object[] array = linkedList.toArray();
        System.out.println("Array: " + java.util.Arrays.toString(array));

        // 清空 LinkedList
        linkedList.clear();

        // 判断是否为空
        boolean isEmpty = linkedList.isEmpty();
        System.out.println("Is Empty: " + isEmpty);
    }
}

以下情况使用 ArrayList :

  • 频繁访问列表中的某一个元素。
  • 只需要在列表末尾进行添加和删除元素操作。

以下情况使用 LinkedList :

  • 你需要通过循环迭代来访问列表中的某些元素。
  • 需要频繁的在列表开头、中间、末尾等位置进行添加和删除元素操作。

2.3、Vector

//构造方法
public Vector()//使用指定的初始容量和等于0的容量增量构造一个空向量。    
public Vector(int initialCapacity)//构造一个空向量,使其内部数据数组的大小,其标准容量增量为零。   
public Vector(Collection<? extends E> c)//构造一个包含指定 collection 中的元素的向量    
public Vector(int initialCapacity,int capacityIncrement)//使用指定的初始容量和容量增量构造一个空的向量    

代码示例

import java.util.Vector;
import java.util.Enumeration;

public class VectorExample {
    public static void main(String[] args) {
        // 创建 Vector
        Vector<String> vector = new Vector<>();

        // 添加元素
        vector.add("Apple");
        vector.add("Banana");
        vector.add("Orange");

        // 获取元素
        String firstElement = vector.get(0);
        System.out.println("First Element: " + firstElement);

        // 修改元素
        vector.set(1, "Grapes");

        // 删除元素
        vector.remove("Orange");

        // 获取 Vector 大小
        int size = vector.size();
        System.out.println("Size: " + size);

        // 判断是否包含某个元素
        boolean containsBanana = vector.contains("Banana");
        System.out.println("Contains Banana: " + containsBanana);

        // 遍历 Vector(使用增强 for 循环)
        System.out.println("Iterating using enhanced for loop:");
        for (String fruit : vector) {
            System.out.println(fruit);
        }

        // 遍历 Vector(使用 Enumeration)
        System.out.println("Iterating using Enumeration:");
        Enumeration<String> enumeration = vector.elements();
        while (enumeration.hasMoreElements()) {
            String fruit = enumeration.nextElement();
            System.out.println(fruit);
        }

        // 转换为数组
        Object[] array = vector.toArray();
        System.out.println("Array: " + java.util.Arrays.toString(array));

        // 清空 Vector
        vector.clear();

        // 判断是否为空
        boolean isEmpty = vector.isEmpty();
        System.out.println("Is Empty: " + isEmpty);
    }
}

2.4、区别

ArrayListLinkedListVector
实现方法动态数组双向链表动态数组
线程是否安全非线程安全非线程安全线程安全
适用场景适用于需要频繁随机访问元素,而且不涉及多线程的场景。适用于需要频繁插入和删除元素的场景,但不涉及多线程。由于线程安全性带来的性能损失,不推荐在单线程环境下使用。

(1)ArrayList:底层数据结构是数组,查询快,增删慢,线程不安全,效率高,可以存储重复元素
(2)LinkedList 底层数据结构是链表,查询慢,增删快,线程不安全,效率高,可以存储重复元素
(3)Vector:底层数据结构是数组,查询快,增删慢,线程安全,效率低,可以存储重复元素

在多线程环境下,如果需要线程安全,可以考虑使用 Collections.synchronizedList() 来包装 ArrayListLinkedList

三、Set集合

Set 是 Java 集合框架中的一种接口,它代表无序、不允许重复元素的集合。需要实现类来进行操作。

特点:

  • 不允许有重复的值
  • 没有索引(不能使用普通for循环进行遍历)

3.1、HashSet集合

特点:

  • 底层结构为“哈希表”
  • 集合对读写顺序不做保证
  • 允许有null值
  • Set集合内容不允许重复
  • 没有索引

HashSet 类位于 java.util 包中,使用前需要引入它,语法格式如下:

import java.util.HashSet; // 引入 HashSet 类

以下实例我们创建一个 HashSet 对象 sites,用于保存字符串元素:

HashSet<String> sites = new HashSet<String>();

代码示例:

import java.util.HashSet;

/**
 * @BelongsProject: Test
 * @BelongsPackage: PACKAGE_NAME
 * @Author: Jorya
 * @CreateTime: 2023-11-22  16:20
 * @Description: TODO
 * @Version: 1.0
 */
public class HashSetTest {
    public static void main(String[] args) {
        HashSet<String> sites = new HashSet<String>();
        sites.add("Google");
        sites.add("Jorya");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Jorya");  // 重复的元素不会被添加
        System.out.println(sites.size());//计算元素数量
        System.out.println(sites);
        System.out.println(sites.contains("Taobao"));//true
        sites.remove("Taobao");  // 删除元素,删除成功返回 true,否则为 false
        sites.clear();//删除集合所有元素
    }
}

3.2、LinkedHashSet集合

特点:

  • LinkedHashSet是哈希表和链表实现的Set接口,具有可预测的读写顺序。

  • 有链表来保证元素有序

  • 有哈希表来保证元素的唯一性

import java.util.HashSet;
public class LinkedHashSetTest {
    public static void main(String[] args) {
        LinkedHashSet<String> sites = new LinkedHashSet<String>();
        sites.add("Google");
        sites.add("Jorya");
        sites.add("Taobao");
        sites.add("Zhihu");
        sites.add("Jorya");  // 重复的元素不会被添加
        System.out.println(sites);
    }
}

3.3、TreeSet集合

特点:

  • 集合底层是二叉树
  • TreeSet集合中的元素,和TreeMap集合中的key部分一样
  • 元素是无序不可重复、可以按照大小顺序自动排序

四、Map集合

Map键值对集合,集合中按Key-Value键值对方式存储

在这里插入图片描述

4.1、HashMap

特点:

  • 无序,key不可重复
  • key,value都可以为null, key为null的时候存储在HashMap的第一个位置
  • 当key相同时,新的value会覆盖旧的value

4.2、TreeMap

特点:

  • 底层是红黑树 ,无序 key不可重复
  • 存储映射的关系过程中,需要key使用 自然排序或传递比较器(比较器根据key进行排序)
  • key不能为null ,value可以为null
  • 添加相同 key 时,新的value会覆盖旧的value(底层:自然排序的compareTo() 或比较器compare()
  • 方法返回值为0,调用t.setValue(value),实现新的值覆盖旧的值)

4.3、HashTable

特点:

  • 无序、key不可重复
  • key,value不可为空
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

威威猫的栗子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值