Java集合详解

简介: 笔记

一、集合简介


集合本质是基于某种数据结构数据容器。常见的数据结构:数组(Array)、集(Set)、队列 (Queue)、链表(Linkedlist)、树(Tree)、堆(Heap)、栈(Stack)和映射(Map)等结构。


Java中提供了丰富的集合接口和类,它们来自于java.util包。如图所示是Java主要的集合接口和 类,从图中可见Java集合类型分为:Collection和Map,Collection子接口有:Set、Queue和List等接口。 每一种集合接口描述了一种数据结构。

1.png

在Java SE中List名称的类型有两个,一个是java.util.List,另外一个是java.awt.List。 java.util.List是一个接口,而java.awt.List是一个类,用于图形用户界面开 发,它是一个图形界面中的组件。学习Java中的集合,首先从两大接口入手,重点掌握List、Set和Map三个接口,熟悉这些接 口中提供的方法。然后再熟悉这些接口的实现类,并了解不同实现类之间的区别。


二、List集合


List集合中的元素是有序的,可以重复出现。List接口的实现类有:ArrayList 和 LinkedList。ArrayList是基于动态数组数据结构的实现,LinkedList 是基于链表数据结构的实现。ArrayList访问元素速度优于LinkedList,LinkedList占用的内存空间比较 大,但LinkedList在批量插入或删除数据时优于ArrayList。


(1)常用方法

List接口继承自Collection接口,List接口中的很多方法都继承自Collection接口的。List接口中常用方法如下。


操作元素

get(int index):返回List集合中指定位置的元素。

set(int index, Object element):用指定元素替换List集合中指定位置的元素。

add(Object element):在List集合的尾部添加指定的元素。该方法是从Collection集合继承 过来的。

add(int index, Object element):在List集合的指定位置插入指定元素。 remove(int index):移除List集合中指定位置的元素。

remove(Object element):如果List集合中存在指定元素,则从List集合中移除第一次出现的 指定元素。该方法是从Collection集合继承过来的。

clear():从List集合中移除所有元素。该方法是从Collection集合继承过来的。

判断元素

isEmpty():判断List集合中是否有元素,没有返回true,有返回false。该方法是从 Collection集合继承过来的。

contains(Object element):判断List集合中是否包含指定元素,包含返回true,不包含返回 false。该方法是从Collection集合继承过来的。

查询元素

indexOf(Object o):从前往后查找List集合元素,返回第一次出现指定元素的索引,如果

此列表不包含该元素,则返回-1。

lastIndexOf(Object o):从后往前查找List集合元素,返回第一次出现指定元素的索引,如果此列表不包含该元素,则返回-1。

其他

iterator():返回迭代器(Iterator)对象,迭代器对象用于遍历集合。该方法是从Collection 集合继承过来的。

size():返回List集合中的元素数,返回值是int类型。该方法是从Collection集合继承过来 的。

subList(int fromIndex, int toIndex):返回List集合中指定的 fromIndex(包括 )和 toIndex(不包括)之间的元素集合,返回值为List集合。

代码如下:

package 集合.list集合;
import  java.util.ArrayList;
import java.util.List;
//list集合:有序,重复
public class HelloWorld {
    public static void main(String[] args) {
//
        List list = new ArrayList();
        String b = "B";
//       向集合中添加元素
        list.add("A");
        list.add(b);
        list.add("C");
        list.add(b);
        list.add("D");
        list.add("E");
//        打印集合的元素个数
        System.out.println("集合 size = "+list.size());
//        打印集合
        System.out.println(list);
//从前往后查找b元素
        System.out.println("indexOf(\"B\") = " +list.indexOf(b));
//       从后往前查找"B"元素
        System.out.println("lastindexOf(\"B\") = " +list.lastIndexOf(b));
        //删除集合中第一个"B"元素
        list.remove(b);
        System.out.println("remove(3)前: "+list);
        //判断集合中是否包含"B"元素
        System.out.println("是否包含\"B\":" + list.contains(b));
        //删除集合第4个元素
        list.remove(3);
        System.out.println("remove(3)后: " + list);
        //判断集合是否为空
        System.out.println("list集合是空的:" + list.isEmpty());
        System.out.println("替换前:" + list); //替换集合第2个元素
        list.set(1, "F");
        System.out.println("替换后:" + list);
        //清空集合
        list.clear();
        System.out.println(list);
        // 重新添加元素
        list.add(1);// 发生自动装箱
        list.add(3);
        int item = (Integer)list.get(0);//发生自动拆箱
    }
}

运行结果:

集合 size = 6
[A, B, C, B, D, E]
indexOf("B") = 1
lastindexOf("B") = 3
remove(3)前: [A, C, B, D, E]
是否包含"B":true
remove(3)后: [A, C, B, E]
list集合是空的:false
替换前:[A, C, B, E]
替换后:[A, F, B, E]
[]

(2)遍历集合

集合最常用的操作之一是遍历,遍历就是将集合中的每一个元素取出来,进行操作或计算。List集合遍历有三种方法:


使用for循环遍历:List集合可以使用for循环进行遍历,for循环中有循环变量,通过循环变量可

以访问List集合中的元素。

使用for-each循环遍历:for-each循环是针对遍历各种类型集合而推出的,笔者推荐使用这种遍历

方法。

使用迭代器遍历:Java提供了多种迭代器,List集合可以使用Iterator和ListIterator迭代器。

代码如下:

package 集合.list集合遍历;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class HelloWorld {
    public static void main(String[] args) {
        List list = new ArrayList();
        String b = "B";
//       向集合中添加元素
        list.add("A");
        list.add(b);
        list.add("C");
        list.add(b);
        list.add("D");
        list.add("E");
//        打印集合
        System.out.println(list);
//        for循环遍历集合
        System.out.println("--1.使用for循环遍历--");
        for (int i = 0;i<list.size();i++){
//            System.out.println(list.get(i));
            System.out.printf("读取集合元素(%d): %s \n", i, list.get(i));
        }
        // 2.使用for-each循环遍历
        System.out.println("--2.使用for-each循环遍历--");
        for (Object items:list){
            String s = (String) items;
            System.out.println("读取集合元素:"+s);
        }
        // 3.使用迭代器遍历
        System.out.println("--3.使用迭代器遍历--");
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            Object items = iterator.next();
            String s = (String)items;
            System.out.println("读取集合元素:"+s);
        }
    }
}


运行结果:

[A, B, C, B, D, E]
--1.使用for循环遍历--
读取集合元素(0): A 
读取集合元素(1): B 
读取集合元素(2): C 
读取集合元素(3): B 
读取集合元素(4): D 
读取集合元素(5): E 
--2.使用for-each循环遍历--
读取集合元素:A
读取集合元素:B
读取集合元素:C
读取集合元素:B
读取集合元素:D
读取集合元素:E
--3.使用迭代器遍历--
读取集合元素:A
读取集合元素:B
读取集合元素:C
读取集合元素:B
读取集合元素:D
读取集合元素:E

二、Set集合


Set集合是由一串无序的,不能重复的相同类型元素构成的集合。List集合强调的是有序,Set集合强调的是不重复。当不考虑顺序,且没有重复元素时,Set集合和List集 合可以互相替换的。Set接口直接实现类主要是HashSet,HashSet是基于散列表数据结构的实现。


(1)常用方法

Set接口也继承自Collection接口,Set接口中大部分都是继承自Collection接口,这些方法如下。


操作元素

add(Object element):在Set集合的尾部添加指定的元素。该方法是从Collection集合继承过来的。

remove(Object element):如果Set集合中存在指定元素,则从Set集合中移除该元素。该方法是从Collection集合继承过来的。

clear():从Set集合中移除所有元素。该方法是从Collection集合继承过来的。

判断元素

isEmpty():判断Set集合中是否有元素,没有返回true,有返回false。该方法是从 Collection集合继承过来的。

contains(Object element):判断Set集合中是否包含指定元素,包含返回true,不包含返回 false。该方法是从Collection集合继承过来的。

其他

iterator():返回迭代器(Iterator)对象,迭代器对象用于遍历集合。该方法是从Collection

集合继承过来的。

size():返回Set集合中的元素数,返回值是int类型。该方法是从Collection集合继承过来的。

代码如下:

//set集合:无序,不重复
import java.util.HashSet;
public class Set {
    public static void main(String[] args) {
        java.util.Set set = new HashSet();
        String b = "B";
// 向集合中添加元素
        set.add("A");
        set.add(b);
        set.add("C");
        set.add(b);
        set.add("D");
        set.add("E");
//        打印集合个数
        System.out.println("集合size = "+set.size());
//        打印集合
        System.out.println(set);
//       删除集合中的B元素
        set.remove(b);
//        判断集合中是否包含"B"元素
        System.out.println("判断是否包含B元素"+set.contains(b));
//        判断集合是否为空
        System.out.println("判断集合是否为空"+set.isEmpty());
//        清空集合
        set.clear();
        //        打印集合
        System.out.println(set);
    }
}

运行结果:

集合size = 5
[A, B, C, D, E]
判断是否包含B元素false
判断集合是否为空false
[]

(2)遍历集合

Set集合中的元素由于没有序号,所以不能使用for循环进行遍历,但可以使用for-each循环和迭代器进 行遍历。事实上这两种遍历方法也是继承自Collection集合,也就是说所有的Collection集合类型都有这 两种遍历方式。

代码如下:

public class Bianli {
    public static void main(String[] args) {
        Set set = new HashSet();
        String b = "B";
// 向集合中添加元素
        set.add("A");
        set.add(b);
        set.add("C");
        set.add(b);
        set.add("D");
        set.add("E");
        //        打印集合
        System.out.println(set);
//        1,使用增强for遍历
        System.out.println("--1,使用增强for遍历--");
        for (Object item : set){
            String s = (String)item;
            System.out.println(s);
        }
//        2.使用迭代器遍历集合
        System.out.println("--2.使用迭代器遍历集合--");
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            Object item  = iterator.next();
            String s = (String)item;
            System.out.println("读取集合"+s);
        }
    }
}


运行结果:

[A, B, C, D, E]
--1,使用增强for遍历--
A
B
C
D
E
--2.使用迭代器遍历集合--
读取集合A
读取集合B
读取集合C
读取集合D
读取集合E

三、Map集合


Map(映射)集合表示一种非常复杂的集合,允许按照某个键来访问元素。Map集合是由两个集合构 成的,一个是键(key)集合,一个是值(value)集合。键集合是Set类型,因此不能有重复的元素。 而值集合是Collection类型,可以有重复的元素。Map集合中的键和值是成对出现的。Map接口直接实现类主要是HashMap,HashMap是基于散列表数据结构的实现。


(1)常用方法

Map集合中包含两个集合(键和值),所以操作起来比较麻烦,Map接口提供很多方法用来管理和操 作集合。主要的方法如下。


操作元素

get(Object key):返回指定键所对应的值;如果Map集合中不包含该键值对,则返回null。 put(Object key, Object value):指定键值对添加到集合中。

remove(Object key):移除键值对。

clear():移除Map集合中所有键值对。

判断元素

isEmpty():判断Map集合中是否有键值对,没有返回true,有返回false。

containsKey(Object key):判断键集合中是否包含指定元素,包含返回true,不包含返回false。

containsValue(Object value):判断值集合中是否包含指定元素,包含返回true,不包含返回false。

查看集合

keySet():返回Map中的所有键集合,返回值是Set类型。

values():返回Map中的所有值集合,返回值是Collection类型。

size():返回Map集合中键值对数。

代码如下:

package 集合.map集合;
import java.util.HashMap;
public class Map {
    public static void main(String[] args) {
        java.util.Map map = new HashMap();
        map.put(101,"A");
        map.put(102, "B");
        map.put(103, "C");
        map.put(104, "D");
//        B重复
        map.put(105, "B");
//把102的值换成E
        map.put(102, "E");
//        打印集合
        System.out.println(map);
//        打印集合元素个数
        System.out.println("集合size="+map.size());
//        通过键取值
        System.out.println("102-"+map.get(102));
        System.out.println("105-"+map.get(105));
//        删除键值对
        map.remove(102);
        System.out.println(map);
//        判断集合中是否包含105
        System.out.println("集合中是否包含102"+map.containsKey(105));
//        集合中是否包含"A"
        System.out.println("集合中是否包含A"+map.containsValue("A"));
//        判断集合是否为空
        System.out.println("集合是否为空"+map.isEmpty());
//        清空集合
        map.clear();
        System.out.println(map);
    }
}

运行结果:

{101=A, 102=E, 103=C, 104=D, 105=B}
集合size=5
102-E
105-B
{101=A, 103=C, 104=D, 105=B}
集合中是否包含102true
集合中是否包含Atrue
集合是否为空false
{}

(2)遍历集合

Map集合遍历与List和Set集合不同,Map有两个集合,因此遍历时可以只遍历值的集合,也可以只遍历键的集合,也可以同时遍历。这些遍历过程都可以使用for-each循环和迭代器进行遍历。

代码如下:

package 集合.map集合遍历;
import java.util.*;
public class Mapbianli {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put(101,"A");
        map.put(102, "B");
        map.put(103, "C");
        map.put(104, "D");
//        使用增强for循环遍历
        System.out.println("使用增强for循环遍历");
//        获得键集合
        Set keys  = map.keySet();
        for (Object key:keys){
//            自动拆箱
            int ikey = (Integer) key;
//            自动装箱
            String value = (String)map.get(ikey);
            System.out.printf("key=%d-value=%s \n",ikey,value);
        }
//        使用迭代器遍历集合
        System.out.println("使用迭代器遍历集合");
//        获得值集合
        Collection values = map.values();
//        遍历值集合
        Iterator iterator = values.iterator();
        while (iterator.hasNext()){
            Object item = iterator.next();
            String s = (String)item;
            System.out.println("集合元素集合:"+s);
        }
    }
}


运行结果:

使用增强for循环遍历
key=101-value=A 
key=102-value=B 
key=103-value=C 
key=104-value=D 
使用迭代器遍历集合
集合元素集合:A
集合元素集合:B
集合元素集合:C
集合元素集合:D



相关文章
|
2月前
|
安全 Java 容器
【Java集合类面试二十七】、谈谈CopyOnWriteArrayList的原理
CopyOnWriteArrayList是一种线程安全的ArrayList,通过在写操作时复制新数组来保证线程安全,适用于读多写少的场景,但可能因内存占用和无法保证实时性而有性能问题。
|
2月前
|
存储 安全 Java
【Java集合类面试二十五】、有哪些线程安全的List?
线程安全的List包括Vector、Collections.SynchronizedList和CopyOnWriteArrayList,其中CopyOnWriteArrayList通过复制底层数组实现写操作,提供了最优的线程安全性能。
|
2月前
|
Java
【Java集合类面试二十八】、说一说TreeSet和HashSet的区别
HashSet基于哈希表实现,无序且可以有一个null元素;TreeSet基于红黑树实现,支持排序,不允许null元素。
|
2月前
|
Java
【Java集合类面试二十三】、List和Set有什么区别?
List和Set的主要区别在于List是一个有序且允许元素重复的集合,而Set是一个无序且元素不重复的集合。
|
2月前
|
Java
【Java集合类面试二十六】、介绍一下ArrayList的数据结构?
ArrayList是基于可动态扩展的数组实现的,支持快速随机访问,但在插入和删除操作时可能需要数组复制而性能较差。
|
2月前
|
存储 Java 索引
【Java集合类面试二十四】、ArrayList和LinkedList有什么区别?
ArrayList基于动态数组实现,支持快速随机访问;LinkedList基于双向链表实现,插入和删除操作更高效,但占用更多内存。
|
27天前
|
安全 Java API
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
String常量池、String、StringBuffer、Stringbuilder有什么区别、List与Set的区别、ArrayList和LinkedList的区别、HashMap底层原理、ConcurrentHashMap、HashMap和Hashtable的区别、泛型擦除、ABA问题、IO多路复用、BIO、NIO、O、异常处理机制、反射
【Java面试题汇总】Java基础篇——String+集合+泛型+IO+异常+反射(2023版)
|
6天前
|
存储 算法 安全
深入理解Java中的集合框架
【9月更文挑战第34天】本文将带你走进Java的集合框架,探索其背后的设计哲学和实现细节。我们将从集合的基本概念出发,逐步深入到具体的接口和类的实现,最后通过一个实际的例子来展示如何在Java程序中高效地使用集合。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角和深度理解。
12 1
|
16天前
|
存储 安全 Java
Java 常用集合分类
Java 常用集合分类
14 2
|
2天前
|
存储 分布式计算 Java
Stream很好,Map很酷,但答应我别用toMap():Java开发中的高效集合操作
在Java的世界里,Stream API和Map集合无疑是两大强大的工具,它们极大地简化了数据处理和集合操作的复杂度。然而,在享受这些便利的同时,我们也应当警惕一些潜在的陷阱,尤其是当Stream与Map结合使用时。本文将深入探讨Stream与Map的优雅用法,并特别指出在使用toMap()方法时需要注意的问题,旨在帮助大家在工作中更高效、更安全地使用这些技术。
8 0