Java容器合集

Java容器合集Array 数组 Collection List ArrayList LinkedList Set HashSet LinkedHashSe TreeSet Map java 容器

大家好,欢迎来到IT知识分享网。

关于这些容器的底层实现、大小扩容机制、线程安全性等可以查看这个:

 JAVA容器详解

  

浅谈

  • 容器: 容器是能够盛放物质的器皿,比如水杯,可以盛放水
  • 编程语言中的容器: 用于存储数据的数据结构,称为容器

Java中的容器可以整体认为三类: Array、Collection 和 Map,图中加粗是重点学习对象

Java容器合集

(Collection里其实还有一个Queue队列,在开头的跳转链接里,很少提到)

泛型类

其它语言的类似容器

   

Array数组

初始化(动与静)

动态初始化

// 动态初始化:数组动态初始化就是只给定数组长度, 由系统给出默认初始化值 // 动态初始化格式:数组类型[] 数组名 = new 数组类型[数组长度] // 示例: int[] arr = new int[3] // 数组类型为int类型, 数组名为arr, 数组长度为3 // 示例: 动态初始化一个长度为5的数组, 并循环打印内部的所有元素 public class DemoTh { public static void main(String[] args) { // 动态初始化一个长度为5的数组 int[] arr = new int[5]; System.out.println(arr); } }

静态初始化

// 静态初始化: 数组静态初始化是指在创建数组时, 直接将元素确定. // 静态初始化格式: // 完整版:数据类型[] 数组名 = new 数据类型[]{元素1, 元素2, ....} // 简化版:数组类型[] 数组名 = {元素1, 元素2, ....} // 示例:创建一个包含1, 3, 5, 7, 9的数组, 并遍历输出其每一个元素 public class DemoOneToNine { public static void main(String[] args) { // 静态初始化数组 int[] arr = {1, 3, 5, 7, 9}; System.out.println(arr); } }

CRUD

增:看初始化

查:

1、索引取值

  • 索引即下标,代表元素在数组中的位置。Java数组的索引从0开始
public class DemoOneToNine { public static void main(String[] args) { // 静态初始化数组 int[] arr = {1, 3, 5, 7, 9}; System.out.println(arr[3]); // 7 } }

2、遍历

// for循环示例: 按索引取出元素 public class DemoOneToNine { public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5}; for (int i = 0;i<arr.length;i++) { System.out.println(arr[i]); }; } }
// for循环示例: 直接遍历出元素 public class DemoOneToNine { public static void main(String[] args) { int[] arr = {1, 2, 3, 4, 5}; for(int item:arr) { System.out.println(item); } } }

改:

public class Test01 { public static void main(String[] args) { // 静态初始化数组 int[] arr = {1, 3, 5, 7, 9}; arr[0] = 666; for(int item:arr) { System.out.println(item); } } }

删:

走进底层

栈与堆

  • 栈:保存局部变量的值,包括:基本数据类型的值、类的实例(堆区对象的引用(指针)。
  • 堆:用来存放动态产生的数据,比如new出来的对象。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。因为同一个类的对象拥有各自的成员变量,存储在各自的堆中,但是他们共享该类的方法,并不是每创建一个对象就把成员方法复制一次。

一个数组的诞生

public class JavaMem { public static void main(String[] args) { int[] arr = {1, 2, 3}; System.out.println(arr); } }

Java容器合集

多数组

arr2 = arr1

public class JavaMem { public static void main(String[] args) { int[] arr1 = {1, 2, 3}; int[] arr2 = arr1; System.out.println(arr1[0]); // 1 System.out.println(arr2[0]); // 1 arr1[0] = 66; System.out.println(arr1[0]); // 66 System.out.println(arr2[0]); // 1 } }

arr2 = {arr1[0], arr1[1], arr1[2]}

public class JavaMem { public static void main(String[] args) { int[] arr1 = {1, 2, 3}; int[] arr2 = {arr1[0], arr1[1], arr1[2]}; System.out.println(arr1[0]); // 1 System.out.println(arr2[0]); // 1 arr1[0] = 666; System.out.println(arr1[0]); // 66 System.out.println(arr2[0]); // 66 } }

避坑指南

索引越界

        索引越界是指使用索引获取数组元素时, 使用的索引不能超过数组元素的最大索引值, 超过后无法通过改索引获取指定的元素, 就会出现索引越界错误, 异常名称位: ArrayIndexOutOfBoundsException

空指针异常

        当一个数组对象被创建了, 当使用的过程中如果让数组对象指向了null, 即将null赋值给数组, 意味着变量arr将不会再保存数组的内存地址,也就不允许再操作数组了,因此运行的时候会抛出 NullPointerException 空指针异常。

小试牛刀

找出数组的最大值

public class GetMax { public static void main(String[] args) { int[] my_arr = {1, 5, 2, 0, -9, 8, 4}; int max = my_arr[0]; for (int i = 1; i < my_arr.length; i++) { if (my_arr[i] > max) { max = my_arr[i]; } } System.out.println(max); } }

返回两个元素的和等于定值,的这两个元素的索引

public class FindTarget { public static void main(String[] args) { int target = 8; int[] arr = {1, 3, 5, 7, 9}; for (int i = 0; i < arr.length; i++) { for (int j = i + 1; j < arr.length; j++) { if (arr[i] + arr[j] == target) { System.out.println("索引分别为: " + i + "," + j); } } } } }

   

Collection

List部落

  • List集合为有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素, 并搜索列表中的元素
  • 列表通常允许重复的元素
  • 特点:(1) 有索引 (2) 可以存储重复元素 (3) 元素存取有序

方法

方法名

描述

void add(int index,E element)

在此集合中的指定位置插入指定的元素

E remove(int index)

删除指定索引处的元素,返回被删除的元素

E set(int index,E element)

修改指定索引处的元素,返回被修改的元素

E get(int index)

返回指定索引处的元素

ArrayList

        在java中ArrayList提供一种存储空间可变的存储模型, 存储的数据容量是可以发生改变的. ArrayList底层是「数组」实现的, 长度可以变化.

方法

方法名

说明

public boolean add(E e)

将指定的元素追加到此集合的末尾

public void add(int index,E element)

在此集合中的指定位置插入指定的元素

public boolean remove(Object o)

删除指定的元素,返回删除是否成功

public E remove(int index)

删除指定索引处的元素,返回被删除的元素

public E set(int index,E element)

修改指定索引处的元素,返回被修改的元素

public E get(int index)

返回指定索引处的元素

public int size()

返回集合中的元素的个数

import java.util.ArrayList; public class ArrayListDemo { public static void main(String[] args) { //创建ArrayList集合对象, 添加四个元素, 并输出在控制台中 ArrayList<String> al = new ArrayList<>(); al.add("Hello"); al.add("World"); al.add("Hello"); al.add("Java"); System.out.println("al的值:" + al); //获取索引为1的元素, 输出在控制台中 System.out.println("al索引为1的元素: " + al.get(1)); //修改索引为3的元素为"Hi" al.set(3,"Hi"); //查看修改后的al System.out.println("修改索引为3的元素后的al: " + al); //移除索引为0的元素后输出al al.remove(0); System.out.println("移除索引为0的元素后的al: " + al); //移除内容为"Java"的元素后输出al al.remove("Java"); System.out.println("移除Java后的al: " + al); } }
遍历
import java.util.ArrayList; public class ArrayListIterDemo { public static void main(String[] args) { ArrayList<String> al = new ArrayList<>(); al.add("I"); al.add("love"); al.add("you"); //普通for遍历 for (int i=0;i<al.size();i++){ System.out.println(al.get(i)); }; // 增强for遍历 for (String item : al) { System.out.println(item); } } }

LinkedList

        LinkedList功能与ArrayList一样,同样是一个List的实现类,功能也是存储数据使用。但LinkedList与ArrayList本质完全不同。

  • ArrayList:底层有数组实现
  • LinkedList:底层有链表实现
方法(特有)

方法名

说明

public void addFirst(E e)

在该列表开头插入指定的元素

public void addLast(E e)

将指定的元素追加到此列表的末尾

public E getFirst()

返回此列表中的第一个元素

public E getLast()

返回此列表中的第一个元素

public E removeFirst()

从此列表中删除并返回第一个元素

public E removeLast()

从此列表中删除并返回最后一个元素

import java.util.LinkedList; public class LinkedListDemo { public static void main(String[] args) { LinkedList<Integer> numbers_linklist = new LinkedList<>(); numbers_linklist.add(1); numbers_linklist.add(2); numbers_linklist.add(3); numbers_linklist.add(4); numbers_linklist.add(5); // addFirst方法 numbers_linklist.addFirst(0); System.out.println(numbers_linklist); // addLast方法 numbers_linklist.addLast(6); System.out.println(numbers_linklist); // getFirst方法 System.out.println(numbers_linklist.getFirst()); // getLast方法 System.out.println(numbers_linklist.getLast()); // removeFirst方法 numbers_linklist.removeFirst(); System.out.println(numbers_linklist); // removeLast方法 numbers_linklist.removeLast(); System.out.println(numbers_linklist); } }

Set部落

        Set为集合,不包含重复元素的集合, 并且最多只有一个空元素。

方法

方法名

说明

add(E e)

如果指定的元素不存在,则将其指定的元素添加(可选操作)。

clear()

从此集合中删除所有元素(可选操作)。

contains(Objcet o)

如果此集合包含指定的元素,则返回 true 。

equals(Object o)

将指定的对象与此集合进行比较以实现相等。

hashCode()

返回此集合的哈希码值。

isEmpty()

如果此集合不包含元素,则返回 true 。

remove(Object o)

如果存在,则从该集合中删除指定的元素(可选操作)。

size()

返回此集合中的元素数(其基数)。

toArray()

返回一个包含此集合中所有元素的数组。

HashSet

  • 底层数据结构是哈希表
  • 对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
  • 没有带索引的方法,所以不能使用普通for循环遍历(可以使用增强for循环和迭代器实现遍历)
  • 由于是Set集合,所以是不包含重复元素的集合
唯一性

前置知识:HashTable: 哈希表;HashCode: 哈希值

  • a.根据对象的哈希值计算存储位置(哈希值对16取模即可得到存储位置, 一个HashSet默认存储16个元素)
    • 如果当前位置没有元素则直接存入
    • 如果当前位置有元素存在,则进入第二步
  • b.当前元素和已经存在的元素比较哈希值
    • 如果哈希值不同,则将当前元素进行存储
    • 如果哈希值相同,则进入第三
  • c.通过equals()方法比较两个元素的内容
    • 如果内容不相同,则将当前元素进行存储
    • 如果内容相同,则不存储当前元素

Java容器合集

LinkedHashSet

  • 哈希表和链表实现的Set接口,具有可预测的迭代次序
  • 由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
  • 由哈希表保证元素唯一,也就是说没有重复的元素

TreeSet

  • TreeSet元素排序方式取决于构造方法
    • Comparable(自然排序): 创建TreeSet对象时, 使用TreeSet()无参构造
    • Comparator(比较器): 创建TreeSet对象时, 使用TreeSet(Comparator comparator)有参构造方法, 传递的参数是Comparator接口的实现类对象, 则根据指定的比较器进行排序
  • TreeSet没有带索引的方法, 所以不能使用普通for循环遍历
  • 由于是Set集合, 所以不能存储重复的元素
public class TreeSetDemo01 { public static void main(String[] args) { //创建集合对象 TreeSet<Integer> ts = new TreeSet<Integer>(); //添加元素 ts.add(10); ts.add(40); ts.add(30); ts.add(50); ts.add(20); ts.add(30); //遍历集合 for(Integer i : ts) { System.out.println(i); } } }
自然排序

        自然排序是在添加对象到集合内部时, 让其按照对象内部的比较方法进行自动排序. 构建TreeSet时使用无参构造方法即可.

        上面的例子中, 我们构建ts对象, 并向其中添加一些整型, 遍历ts对象会发现, 打印的顺序是从小到达的. 经查看Integer类源码发现, Integer底层实现了两个方法, 一个compare方法和compareTo方法, 其中compare负责进行比较, 而compareTo内部调用compare方法, 当前数与另一个数进行比较时, 如果当前数小于那个数, 则返回-1, 如果相等则返回0, 如果当前数大于那个数则返回1. 如果是自定义类实例化而来的对象, 需要自己定义compareTo()方法, 在方法内部定义比较规则.

        需求:定义学生类, 学生类内部定义compareTo方法, 按照学生年龄排序. 将学生类添加至TreeSet对象中, 遍历集合对象

public class Student implements Comparable<Student> { private String name; private int age; public Student(){}; public Student(String name, int age) { this.name = name; this.age = age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public int getAge() { return age; } @Override public int compareTo(Student s) { return this.age - s.age; } }
public class TreeSetDemo { public static void main(String[] args) { TreeSet<Student> ts = new TreeSet<Student>(); Student s1 = new Student("成成", 18); Student s2 = new Student("宝中", 17); Student s3 = new Student("金喜", 20); ts.add(s1); ts.add(s2); ts.add(s3); for (Student stu : ts) { System.out.println(stu.getName()); } } }
比较器排序

        使用比较器排序, 需要自己实现一个比较器, 并在初始化TreeSet时使用有参构造, 并把比较器传入进去, 对象加入TreeSet对象时, 就会按照比较器的规则进行排序了

        需求:定义学生类, 学生类内部定义compareTo方法, 按照学生年龄排序. 将学生类添加至TreeSet对象中, 遍历集合对象

public class Student { private String name; private int age; public Student(){}; public Student(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; } }
public class TreeSetDemo { public static void main(String[] args) { TreeSet<Student> ts = new TreeSet<Student>( new Comparator<Student>() { @Override public int compare(Student s1, Student s2) { return s1.getAge() - s2.getAge(); } } ); Student s1 = new Student("小明", 18); Student s2 = new Student("小红", 17); Student s3 = new Student("小强", 20); ts.add(s1); ts.add(s2); ts.add(s3); for (Student stu : ts) { System.out.println(stu.getName()); }; } }

   

Map

Map为一个接口, 将键映射到值的对象。 Map不能包含重复的键; 每个键可以映射到最多一个值。

interface Map<K,V> K:键的类型;V:值的类型

特点:

  • 键值对映射关系
  • 一个键对应一个值
  • 键不能重复, 值可以重复
  • 元素存取无序

基本使用:

import java.util.HashMap; import java.util.Map; public class MapDemo01 { public static void main(String[] args) { //创建HashMap对象 Map<String, String> m = new HashMap<String, String>(); //添加键值对 m.put("name_1", "Jeremy"); m.put("name_2", "Fish"); //输出 System.out.println(m); //{name_2=Fish, name_1=Jeremy} } }

方法的介绍

//增: - put(key, value): 添加键值对, 返回键对应的值 //删: - remove(key, value): 如果指定的键对应的值为value, 则进行删除 - remove(key): 根据键删除键值对元素, 返回键对应的值 - clear(): 清空所有键值对元素 //改: - put(key, value): 同则修改, 异则添加 //查: - containsKey(key): 判断是否存在某个特定的key, 返回值为布尔值 - containsValue(Value): 判断是否包含指定的值, 返回值为布尔值 - isEmpty(): 判断Map对象是否为空, 返回值为布尔值 - size(): 获取Map对象键值对个数, 返回值为整型 - get(key): 获取指定键的值 - keySet(): 获取所有的键, 返回值为Set类型 - Values(): 获取所有值的集合 - enterSet(): 获取所有键值对对象的集合

示例

import java.util.HashMap; import java.util.Map; public class MapDemo01 { public static void main(String[] args) { Map<String, String> m = new HashMap<String, String>(); m.put("name_1", "Jeremy"); m.put("name_2", "Fish"); System.out.print("put增加键值对后的m为: "); System.out.println(m); //put增加键值对后的m为: {name_2=Fish, name_1=Jeremy} m.remove("name_1", "Jer"); System.out.print("如果键name_1对应的值为Jer, 则移除: "); System.out.println(m); //如果键name_1对应的值为Jer, 则移除: {name_2=Fish, name_1=Jeremy} //直接移除name_1的键值对 m.remove("name_1"); System.out.print("移除name_1的键值对后, m的值: "); System.out.println(m); //移除name_1的键值对后, m的值: {name_2=Fish} //clear()后的m m.clear(); System.out.print("clear()后m的值为: "); System.out.println(m); //clear()后m的值为: {} //空对象m重新添加name_1键值对 m.put("name_1", "Jeremy"); m.put("name_2", "Lucy"); System.out.print("重新添加name_1键值对的m为: "); System.out.println(m); //重新添加name_1键值对的m为: {name_2=Lucy, name_1=Jeremy} //重复添加name_1的键, 但是改变对应的值 m.put("name_1", "LiLi"); System.out.print("使用name_1键的新值覆盖原有值后m的值: "); System.out.println(m); //使用name_1键的新值覆盖原有值后m的值: {name_2=Lucy, name_1=LiLi} //判断是否包含指定的key System.out.println(m.containsKey("name_2")); //true //判断是否包含指定的value System.out.println(m.containsValue("Lucy")); //true //判断是否为空 System.out.println(m.isEmpty()); //false //获取Map对象的长度 System.out.println(m.size()); //2 //获取指定键对应的值 System.out.println(m.get("name_1")); // LiLi //获取所有键的集合 System.out.println(m.keySet()); //[name_2, name_1] //获取所有值的集合 System.out.println(m.values()); //[Lucy, LiLi] //获取所有的键值对 System.out.println(m.entrySet()); //[name_2=Lucy, name_1=LiLi] } }

遍历方式

方式一

使用增强for, 遍历集合的所有键或值进行操作 import java.util.HashMap; import java.util.Map; public class MapDemo02 { public static void main(String[] args) { Map<String, String> m = new HashMap<String, String>(); m.put("name_1", "金喜"); m.put("name_2", "帅帅"); m.put("name_3", "晨阳"); for(String key: m.keySet()){ System.out.println(key); } for (String value:m.values()){ System.out.println(value); } } }

方式二

通过增强for遍历键值对组成的EntrySet对象 import java.util.HashMap; import java.util.Map; import java.util.Set; public class MapDemo03 { public static void main(String[] args) { Map<String, String> m = new HashMap<String, String>(); m.put("name_1", "Jeremy"); m.put("name_2", "刘桂宁"); m.put("name_3", "毕奎成"); Set<Map.Entry<String, String>> items = m.entrySet(); for(Map.Entry<String, String> item:items) { System.out.println("键值对为: " + item); System.out.println("键为: " + item.getKey()); System.out.println("值为: " + item.getValue()); System.out.println("-------------------------"); } } }

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/120412.html

(0)
上一篇 2025-10-29 21:20
下一篇 2025-10-29 21:26

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信