Java 集合

Java 集合

集合框架

集合框架被设计成要满足以下几个目标。

  • 该框架必须是高性能的。基本集合(动态数组,链表,树,哈希表)的实现也必须是高效的。
  • 该框架允许不同类型的集合,以类似的方式工作,具有高度的互操作性。
  • 对一个集合的扩展和适应必须是简单的。

为此,整个集合框架就围绕一组标准接口而设计。你可以直接使用这些接口的标准实现,诸如: LinkedList, HashSet, 和 TreeSet 等,除此之外你也可以通过这些接口实现自己的集合。

Java 集合

从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类。

集合框架是一个用来代表和操纵集合的统一架构。所有的集合框架都包含如下内容:

  • 接口: 是代表集合的抽象数据类型。例如 Collection、List、Set、Map 等。之所以定义多个接口,是为了以不同的方式操作集合对象

  • 实现(类): 是集合接口的具体实现。从本质上讲,它们是可重复使用的数据结构,例如:ArrayList、LinkedList、HashSet、HashMap。

  • 算法: 是实现集合接口的对象里的方法执行的一些有用的计算,例如:搜索和排序。这些算法被称为多态,那是因为相同的方法可以在相似的接口上有着不同的实现。

除了集合,该框架也定义了几个 Map 接口和类。Map 里存储的是键/值对。尽管 Map 不是集合,但是它们完全整合在集合中。

集合接口

集合框架定义了一些接口。本节提供了每个接口的概述:

序号 接口描述
1 Collection 接口 Collection 是最基本的集合接口,一个 Collection 代表一组 Object,即 Collection 的元素, Java不提供直接继承自Collection的类,只提供继承于的子接口(如List和set)。Collection 接口存储一组不唯一,无序的对象。
2 List 接口 List接口是一个有序的 Collection,使用此接口能够精确的控制每个元素插入的位置,能够通过索引(元素在List中位置,类似于数组的下标)来访问List中的元素,第一个元素的索引为 0,而且允许有相同的元素。List 接口存储一组不唯一,有序(插入顺序)的对象。
3 Set Set 具有与 Collection 完全一样的接口,只是行为上不同,Set 不保存重复的元素。Set 接口存储一组唯一,无序的对象。
4 SortedSet 继承于Set保存有序的集合。
5 Map Map 接口存储一组键值对象,提供key(键)到value(值)的映射。
6 Map.Entry 描述在一个Map中的一个元素(键/值对)。是一个 Map 的内部接口。
7 SortedMap 继承于 Map,使 Key 保持在升序排列。
8 Enumeration 这是一个传统的接口和定义的方法,通过它可以枚举(一次获得一个)对象集合中的元素。这个传统接口已被迭代器取代。

Set和List的区别

  • Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
  • Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 。
  • List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 。

Iterator(迭代器)

Java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList和 HashSet等集合。

Iterator 是 Java 迭代器最简单的实现,ListIterator 是 Collection API 中的接口, 它扩展了 Iterator 接口。

迭代器 it 的两个基本操作是 next 、hasNext 和 remove。

调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态。

调用 it.hasNext() 用于检测集合中是否还有元素。

调用 it.remove() 将迭代器返回的元素删除。

获取一个迭代器

集合想获取一个迭代器可以使用 iterator() 方法:

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

public class IteratorTest {
   
    public static void main(String[] args) {
   

        // 创建集合
        List<String> list = new ArrayList<>();
        list.add("Google");
        list.add("Runoob");
        list.add("Taobao");
        list.add("Zhihu");

        // 获取迭代器
        Iterator<String> it = list.iterator();

        // 输出集合中的第一个元素
        System.out.println(it.next());
    }
}

执行以上代码,输出结果如下:

Google

循环集合元素

让迭代器 it 逐个返回集合中所有元素最简单的方法是使用 while 循环:

while(it.hasNext()) {
    System.out.println(it.next());
}

例子:

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

public class IteratorTest {
   
    public static void main(String[] args) {
   

        // 创建集合
        List<String> list = new ArrayList<>();
        list.add("Google");
        list.add("Runoob");
        list.add("Taobao");
        list.add("Zhihu");

        // 获取迭代器
        Iterator<String> it = list.iterator();
        // 输出集合中的所有元素
        while(it.hasNext()) {
   
            System.out.println(it.next());
        }
    }
}

执行以上代码,输出结果如下:

Google
Runoob
Taobao
Zhihu

删除元素

要删除集合中的元素可以使用 remove() 方法。

例子:

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

public class IteratorTest {
   
    public static void main(String[] args) {
   

        // 创建集合
        List<Integer> numbers = new ArrayList<>();
        numbers.add(18);
        numbers.add(9);
        numbers.add(5);
        numbers.add(20);
        Iterator<Integer> it = numbers.iterator();
        while(it.hasNext()) {
   
            Integer i = it.next();
            if(i < 15) {
     
                it.remove();  // 删除小于 15 的元素
            }
        }
        System.out.println(numbers);
    }
}

执行以上代码,输出结果如下:

[18, 20]

遍历 ArrayList

例子:

import java.util.*;
 
public class Test{
   
 public static void main(String[] args) {
   
     List<String> list=new ArrayList<String>();
     list.add("Hello");
     list.add("World");
     list.add("HAHAHAHA");
     //第一种遍历方法使用 For-Each 遍历 List
     for (String str : list) {
               //也可以改写 for(int i=0;i<list.size();i++) 这种形式
        System.out.println(str);
     }
 
     //第二种遍历,把链表变为数组相关的内容进行遍历
     String[] strArray=new String[list.size()];
     list.toArray(strArray);
     for(int i=0;i<strArray.length;i++) //这里也可以改写为 for(String str:strArray) 这种形式
     {
   
        System.out.println(strArray[i]);
     }
     
    //第三种遍历 使用迭代器进行相关遍历
     
     Iterator<String> ite=list.iterator();
     while(ite.hasNext())//判断下一个元素之后有值
     {
   
         System.out.println(ite.next());
     }
 }
}

三种方法都是用来遍历ArrayList集合,第三种方法是采用迭代器的方法,该方法可以不用担心在遍历的过程中会超出集合的长度。

遍历 Map

例子:

import java.util.*;
public class Test{

public static void main(String[] args) {

Map<String, String> map = new HashMap<String, String>();
map.put("1", "value1");
map.put("2", "value2");
map.put("3", "value3");
//第一种:普遍使用,二次取值
System.out.println("通过Map.keySet遍历key和value:");
for (String key : map.keySet()) {

System.out.println("key= "+ key + " and value= " + map.get(key));
}
//第二种
System.out.println("通过Map.entrySet使用iterator遍历key和value:");
Iterator<Map.Entry<String, String>> it = map.entrySet().iterator();
while (it.hasNext()) {

Map.Entry<String, String> entry = it.next();
System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}
//第三种:推荐,尤其是容量大时
System.out.println("通过Map.entrySet遍历key和value");
for (Map.Entry<String, String> entry : map.entrySet()) {

System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}
//第四种
System.out.println("通过Map.values()遍历所有的value,但不能遍历key");
for (String v : map.values()) {

System.out.println("value= " + v);
}
}
}

ArrayList

ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。

ArrayList 继承了 AbstractList ,并实现了 List 接口。

ArrayList 类位于 java.util 包中,使用前需要引入它.

语法:

import java.util.ArrayList; // 引入 ArrayList 类
ArrayList<E> objectName =new ArrayList<>();  // 初始化
  • E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型
  • objectName: 对象名。

ArrayList 是一个数组队列,提供了相关的添加、删除、修改、遍历等功能。

ArrayList可以实现所有可选择的列表操作,允许所有的元素,包括空值。 Array List还提供了内部存储Iist的方法,它能够完全替代 Vector,只有一点例外, Array List不是线程安全的容器。

ArrayList有一个容量的概念,这个数组的容量就是List用来存储元素的容量。

ArrayList不是线程安全的容器,如果多个线程中至少有两个线程修改了 ArrayList的结构的话就会导致线程安全问题,作为替代条件可以使用线程安全的List,应使用

 List list = Collections. synchronizedList(new Arraylist(...))

ArrayList具有fail-fast快速失败机制,能够对 ArrayList作出失败检测。当在迭代集合的过程中该集合在结构上发生改变的时候,就有可能会发生fail-fast,即抛出
ConcurrentModificationException异常。

常用方法

Java ArrayList 常用方法列表如下:

方法 描述
add() 将元素插入到指定位置的 arraylist 中
addAll() 添加集合中的所有元素到 arraylist 中
clear() 删除 arraylist 中的所有元素
clone() 复制一份 arraylist
contains() 判断元素是否在 arraylist
get() 通过索引值获取 arraylist 中的元素
indexOf() 返回 arraylist 中元素的索引值
removeAll() 删除存在于指定集合中的 arraylist 里的所有元素
remove() 删除 arraylist 里的单个元素
size() 返回 arraylist 里元素数量
isEmpty() 判断 arraylist 是否为空
subList() 截取部分 arraylist 的元素
set() 替换 arraylist 中指定索引的元素
sort() 对 arraylist 元素进行排序
toArray() 将 arraylist 转换为数组
toString() 将 arraylist 转换为字符串
ensureCapacity() 设置指定容量大小的 arraylist
lastIndexOf() 返回指定元素在 arraylist 中最后一次出现的位置
retainAll() 保留 arraylist 中在指定集合中也存在的那些元素
containsAll() 查看 arraylist 是否包含指定集合中的所有元素
trimToSize() 将 arraylist 中的容量调整为数组中的元素个数
removeRange() 删除 arraylist 中指定索引之间存在的元素
replaceAll() 将给定的操作内容替换掉数组中每一个元素
removeIf() 删除所有满足特定条件的 arraylist 元素
forEach() 遍历 arraylist 中每一个元素并执行特定操作

ArrayList 排序

Collections 类也是一个非常有用的类,位于 java.util 包中,提供的 sort() 方法可以对字符或数字列表进行排序。

例子:

public class ArrayListTest {

public static void main(String[] args) {

List<String> list = new ArrayList<>();
list.add("Google");
list.add("Runoob");
list.add("Taobao");
list.add("Zhihu");
// 字母排序
Collections.sort(list);
for (String i : list) {

System.out.println(i);
}
}
}

以上实例,执行输出结果为:

Google
Runoob
Taobao
Zhihu

例子:

public class ArrayListTest {

public static void main(String[] args) {

List<Integer> numbers = new ArrayList<>();
numbers.add(18);
numbers.add(9);
numbers.add(5);
numbers.add(20);
//数字排序
Collections.sort(numbers);
for (Integer number : numbers) {

System.out.println(number);
}
}
}

以上实例,执行输出结果为:

5
9
18
20

LinkedList

链表(Linked list)是一种常见的基础数据结构,是一种线性表,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的地址。

链表可分为单向链表和双向链表。

一个单向链表包含两个值: 当前节点的值和一个指向下一个节点的链接。

img

一个双向链表有三个整数值: 数值、向后的节点链接、向前的节点链接。

img

Java LinkedList(链表) 类似于 ArrayList,是一种常用的数据容器。

与 ArrayList 相比,LinkedList 的增加和删除对操作效率更高,而查找和修改的操作效率较低。

以下情况使用 ArrayList :

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

以下情况使用 LinkedList :

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

LinkedList 继承了 AbstractSequentialList 类。

LinkedList 实现了 Queue 接口,可作为队列使用。

LinkedList 实现了 List 接口,可进行列表的相关操作。

LinkedList 实现了 Deque 接口,可作为队列使用。

LinkedList 实现了 Cloneable 接口,可实现克隆。

LinkedList 实现了 java.io.Serializable 接口,即可支持序列化,能通过序列化去传输。

LinkedList 类位于 java.util 包中,使用前需要引入它.

语法:

// 引入 LinkedList 类
import java.util.LinkedList; 
LinkedList<E> list = new LinkedList<E>();   // 普通创建方法
或者
LinkedList<E> list = new LinkedList(Collection<? extends E> c); // 使用集合创建链表

LinkedList所有的操作都可以表现为双向性的,索引到链表的操作将遍历从头到尾,视哪个距离近为遍历顺序。

注意这个实现也不是线程安全的,如果多个线程并发访问链表,并且至少其中的一个线程修改了链表的结构,那么这个链表必须进行外部加锁。或者使用

 List list =Collections. synchronizedList(new Linkedlist(...))

常用方法

方法 描述
public boolean add(E e) 链表末尾添加元素,返回是否成功,成功为 true,失败为 false。
public void add(int index, E element) 向指定位置插入元素。
public boolean addAll(Collection c) 将一个集合的所有元素添加到链表后面,返回是否成功,成功为 true,失败为 false。
public boolean addAll(int index, Collection c) 将一个集合的所有元素添加到链表的指定位置后面,返回是否成功,成功为 true,失败为 false。
public void addFirst(E e) 元素添加到头部。
public void addLast(E e) 元素添加到尾部。
public boolean offer(E e) 向链表末尾添加元素,返回是否成功,成功为 true,失败为 false。
public boolean offerFirst(E e) 头部插入元素,返回是否成功,成功为 true,失败为 false。
public boolean offerLast(E e) 尾部插入元素,返回是否成功,成功为 true,失败为 false。
public void clear() 清空链表。
public E removeFirst() 删除并返回第一个元素。
public E removeLast() 删除并返回最后一个元素。
public boolean remove(Object o) 删除某一元素,返回是否成功,成功为 true,失败为 false。
public E remove(int index) 删除指定位置的元素。
public E poll() 删除并返回第一个元素。
public E remove() 删除并返回第一个元素。
public boolean contains(Object o) 判断是否含有某一元素。
public E get(int index) 返回指定位置的元素。
public E getFirst() 返回第一个元素。
public E getLast() 返回最后一个元素。
public int indexOf(Object o) 查找指定元素从前往后第一次出现的索引。
public int lastIndexOf(Object o) 查找指定元素最后一次出现的索引。
public E peek() 返回第一个元素。
public E element() 返回第一个元素。
public E peekFirst() 返回头部元素。
public E peekLast() 返回尾部元素。
public E set(int index, E element) 设置指定位置的元素。
public Object clone() 克隆该列表。
public Iterator descendingIterator() 返回倒序迭代器。
public int size() 返回链表元素个数。
public ListIterator listIterator(int index) 返回从指定位置开始到末尾的迭代器。
public Object[] toArray() 返回一个由链表元素组成的数组。
public T[] toArray(T[] a) 返回一个由链表元素转换类型而成的数组。

HashSet

HashSet 基于 HashMap 来实现的,是一个不允许有重复元素的集合。

HashSet 允许有 null 值。

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

HashSet 不是线程安全的, 如果多个线程尝试同时修改 HashSet,则最终结果是不确定的。 您必须在多线程访问时显式同步对 HashSet 的并发访问。

HashSet 实现了 Set 接口。

HashSet 中的元素实际上是对象,一些常见的基本类型可以使用它的包装类。

创建一个HashSet对象。

语法:

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

常用方法

Java HashSet 常用方法列表如下:

方法 描述
add(E e) 如果指定的元素尚不存在,则将其添加到此集合中。
clear() 从该集中删除所有元素。
clone() 返回此 HashSet实例的浅表副本:未克隆元素本身。
contains(Object o) 如果此set包含指定的元素,则返回 true
isEmpty() 如果此集合不包含任何元素,则返回 true
iterator() 返回此set中元素的迭代器。
remove(Object o) 如果存在,则从该集合中移除指定的元素。
size() 返回此集合中的元素数(基数)。
spliterator() 在此集合中的元素上创建*late-binding失败快速* Spliterator

HashMap

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

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

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

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

HashMap 的 key 与 value 类型可以相同也可以不同。

HashMap 中的元素实际上是对象,一些常见的基本类型可以使用它的包装类。

创建一个HashMap对象。

语法:

HashMap<K, V> Sites = new HashMap<>();

常用方法

Java HashMap 常用方法列表如下:

方法 描述
clear() 删除 hashMap 中的所有键/值对
clone() 复制一份 hashMap
isEmpty() 判断 hashMap 是否为空
size() 计算 hashMap 中键/值对的数量
put() 将键/值对添加到 hashMap 中
putAll() 将所有键/值对添加到 hashMap 中
putIfAbsent() 如果 hashMap 中不存在指定的键,则将指定的键/值对插入到 hashMap 中。
remove() 删除 hashMap 中指定键 key 的映射关系
containsKey() 检查 hashMap 中是否存在指定的 key 对应的映射关系。
containsValue() 检查 hashMap 中是否存在指定的 value 对应的映射关系。
replace() 替换 hashMap 中是指定的 key 对应的 value。
replaceAll() 将 hashMap 中的所有映射关系替换成给定的函数所执行的结果。
get() 获取指定 key 对应对 value
getOrDefault() 获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值
forEach() 对 hashMap 中的每个映射执行指定的操作。
entrySet() 返回 hashMap 中所有映射项的集合集合视图。
keySet() 返回 hashMap 中所有 key 组成的集合视图。
values() 返回 hashMap 中存在的所有 value 值。
merge() 添加键值对到 hashMap 中
compute() 对 hashMap 中指定 key 的值进行重新计算
computeIfAbsent() 对 hashMap 中指定 key 的值进行重新计算,如果不存在这个 key,则添加到 hasMap 中
computeIfPresent() 对 hashMap 中指定 key 的值进行重新计算,前提是该 key 存在于 hashMap 中。

总结

Java集合框架为程序员提供了预先包装的数据结构和算法来操纵他们。

集合是一个对象,可容纳其他对象的引用。集合接口声明对每一种类型的集合可以执行的操作。

集合框架的类和接口均在java.util包中。

任何对象加入集合类后,自动转变为Object类型,所以在取出的时候,需要进行强制类型转换。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/114430.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 【全网首发】言简意赅的Python全套语法,内附详细知识点和思维导图!【强烈建议收藏!】

    【全网首发】言简意赅的Python全套语法,内附详细知识点和思维导图!【强烈建议收藏!】Python是近几年比较火热的编程语言,至于有多火热?偶尔打开微信公众号,页面下面弹出的是《Python训练营》,打开朋友圈发现有推荐学习Python的课程,打开CSDN,发现热榜第一又是Python推荐文章,不得不说Python的影响力在目前还是比较大的,这和Python社区的宣传力度有着密切的关系!目前学习Python的人有多少呢?那些人在学习Python呢?至于这个问题,我认为没有一个准确的答案,因为每一天学习Python的人都在增加,学习Python被越来越多的人注重,所以要回答这个问题,最好的

  • linux查看iostat_ios命令行怎么打开

    linux查看iostat_ios命令行怎么打开简介iostat主要用于监控系统设备的IO负载情况,iostat首次运行时显示自系统启动开始的各项统计信息,之后运行iostat将显示自上次运行该命令以后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。命令格式及参数iostat[-c|-d][-k|-m][-t][-V][-x][device[…]|ALL][-p[…

  • HeadFirstJava

    HeadFirstJavajava执行过程的来龙去脉源代码——编译器——输出——java虚拟机扩展名为.java——扩展名为.class不要直接用类名点变量来改变属性值,一般都用get、set方法。封装的基本原则:将你

  • 磁盘占用率100%——哪些程序可以禁用(详细版)【还讲到独立显卡、集成显卡、双显卡、固态硬盘卡机卡死卡顿解决】

    磁盘占用率100%——哪些程序可以禁用(详细版)【还讲到独立显卡、集成显卡、双显卡、固态硬盘卡机卡死卡顿解决】我买内存条之前,电脑超级卡的,我不喜欢用完电脑就关机,经常晚上用完就“睡眠、待机”,第二天早上用电脑,一般都打开谷歌浏览器、网易云音乐、有道词典、Eclipse、Oracle、Tomcat、电脑管家、文件资源管理器;我使用Eclipse编写代码,我都输完一行代码,电脑卡的呀,30分钟至一分钟才有反应,这算是快的,最恶心的是“卡至Eclipse软件自己关闭了”!!!所以只能看看哪些服务进程可以禁用…

  • BindingNavigator控件[通俗易懂]

    BindingNavigator控件[通俗易懂]WinForm之中BindingNavigator控件的使用在微软WinForm中,BindingNavigator控件主要用来绑定数据。可以将一个数据集合与该控件绑定,以进行数据联动的显示效果。如图下图所示:那么,下面我们就来用BindingNavigator控件做一下上图所示的效果。分析:该案例以BindingNavigator控件为主线,我们定义一个实体类

  • 走过的laravel-admin 的坑

    走过的laravel-admin 的坑

    2021年10月21日

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号