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



相关文章
|
1月前
|
算法 Java 数据处理
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。
从HashSet到TreeSet,Java集合框架中的Set接口及其实现类以其“不重复性”要求,彻底改变了处理唯一性数据的方式。HashSet基于哈希表实现,提供高效的元素操作;TreeSet则通过红黑树实现元素的自然排序,适合需要有序访问的场景。本文通过示例代码详细介绍了两者的特性和应用场景。
40 6
|
1月前
|
存储 Java
深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。
【10月更文挑战第16天】本文深入探讨了Java集合框架中的HashSet和TreeSet,解析了两者在元素存储上的无序与有序特性。HashSet基于哈希表实现,添加元素时根据哈希值分布,遍历时顺序不可预测;而TreeSet利用红黑树结构,按自然顺序或自定义顺序存储元素,确保遍历时有序输出。文章还提供了示例代码,帮助读者更好地理解这两种集合类型的使用场景和内部机制。
38 3
|
1月前
|
存储 Java 数据处理
Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位
【10月更文挑战第16天】Java Set接口凭借其独特的“不重复”特性,在集合框架中占据重要地位。本文通过快速去重和高效查找两个案例,展示了Set如何简化数据处理流程,提升代码效率。使用HashSet可轻松实现数据去重,而contains方法则提供了快速查找的功能,彰显了Set在处理大量数据时的优势。
33 2
|
1月前
|
存储 算法 Java
Java Set因其“无重复”特性在集合框架中独树一帜
【10月更文挑战第14天】Java Set因其“无重复”特性在集合框架中独树一帜。本文深入解析Set接口及其主要实现类(如HashSet、TreeSet)如何通过特定的数据结构(哈希表、红黑树)确保元素唯一性,并提供最佳实践建议,包括选择合适的Set实现类和正确实现自定义对象的`hashCode()`与`equals()`方法。
31 3
|
11天前
|
Java
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式
Java 8 引入的 Streams 功能强大,提供了一种简洁高效的处理数据集合的方式。本文介绍了 Streams 的基本概念和使用方法,包括创建 Streams、中间操作和终端操作,并通过多个案例详细解析了过滤、映射、归并、排序、分组和并行处理等操作,帮助读者更好地理解和掌握这一重要特性。
21 2
|
11天前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
16天前
|
存储 Java
判断一个元素是否在 Java 中的 Set 集合中
【10月更文挑战第30天】使用`contains()`方法可以方便快捷地判断一个元素是否在Java中的`Set`集合中,但对于自定义对象,需要注意重写`equals()`方法以确保正确的判断结果,同时根据具体的性能需求选择合适的`Set`实现类。
|
16天前
|
存储 Java 开发者
在 Java 中,如何遍历一个 Set 集合?
【10月更文挑战第30天】开发者可以根据具体的需求和代码风格选择合适的遍历方式。增强for循环简洁直观,适用于大多数简单的遍历场景;迭代器则更加灵活,可在遍历过程中进行更多复杂的操作;而Lambda表达式和`forEach`方法则提供了一种更简洁的函数式编程风格的遍历方式。
|
16天前
|
Java 开发者
|
28天前
|
安全 Java 程序员
深入Java集合框架:解密List的Fail-Fast与Fail-Safe机制
本文介绍了 Java 中 List 的遍历和删除操作,重点讨论了快速失败(fail-fast)和安全失败(fail-safe)机制。通过普通 for 循环、迭代器和 foreach 循环的对比,详细解释了各种方法的优缺点及适用场景,特别是在多线程环境下的表现。最后推荐了适合高并发场景的 fail-safe 容器,如 CopyOnWriteArrayList 和 ConcurrentHashMap。
55 5
下一篇
无影云桌面