Java 基础 - 集合框架

集合概述

集合的由来

通常,我们的程序需要根据程序运行时才知道创建多少个对象。但若非程序运行,程序开发阶段,我们根本不知道到底需要多少个数量的对象,甚至不知道它的准确类型。为了满足这些常规的编程需要,我们要求能在任何时候,任何地点创建任意数量的对象,而这些对象用什么来容纳呢?我们首先想到了数组,但是数组只能放统一类型的数据,而且其长度是固定的,那怎么办呢?集合便应运而生了!

集合是什么?

Java集合类存放于 java.util 包中,是一个用来存放对象的容器。

注意:

① 集合只能存放对象。比如你存一个int 型数据放入集合中,其实它是自动转换成 Integer 类后存入的,Java中每一种基本类型都有对应的引用类型。

② 集合存放的是多个对象的引用,对象本身还是放在堆内存中。

③ 集合可以存放不同类型,不限数量的数据类型。

集合和数组的区别

  • 数组存放的类型只能是基本数据类型或引用数据类型,集合中存放的数据类型只能是引用数据类型 。
  • 数组是静态的,一个数组实例具有固定的大小,一旦创建了不能改变容量。而集合是可以动态扩展容量,可以根据需要动态改变大小。
  • 初始化数组时需要声明存放在数组中的数据类型,而集合可以声明或不声明,当不声明时默认为Object类型,Object是Java中的超类,这就意味着一个集合中可以存放混合类型的数据(既存放String类型的数据又存放Integer类型的数据)

集合框架的基础接口

  • Collection:是集合框架的基础接口之一,在Java中不提供该接口的任何直接实现。
  • List:是一个可以包含重复元素的集合。每个元素都有对应的顺序索引,实现类主要有ArrayList、LinkedList等。
  • Set:是一个不能包含重复元素的集合,并且元素没有特定顺序。
  • Map:是用于保存具有映射关系的键值对数据,提供key(键)到value(值)的映射。一个Map不能包含重复的key,每个key最多映射到一个value。
  • Queue:是数据结构中队列结构的实现。在queue中元素具有隐含的顺序,且每个queue都有一个head元素
  • Iterable:是一个迭代器接口,使用该接口可以从集合中每次返回其中的一个元素

集合框架常用集合类

[图片上传失败...(image-7e819-1631774982060)]

Collection接口

Collection接口是Set,Queue,List的父接口。

Collection接口中定义了多种方法可供其子类进行实现,以实现数据操作。

下面是Collection的类结构图:

[图片上传失败...(image-255600-1631774982060)]

Collections工具类

Collections 是一个操作 Set、List 和 Map 等集合的工具类。Collections 中提供了一系列静态的方法对集合元素进行排序、查询和修改等操作,还提供了对集合对象设置不可变、对集合对象实现同步控制等方法。

Collections提供了多个synchronizedXx()方法,把线程不安全的list/Collection/map转换为线程安全0

public class CollectionsTest {
    @Test
    public void test1() {
        List<Integer> list = new ArrayList<>();
        list.add(41);
        list.add(13);
        list.add(55);
        list.add(55);
        //1) reverse(list)方法 反转list中的元素
        Collections.reverse(list); // 对list做修改 没有返回值
        //2) shuffle(list)方法 对list进行随机打乱排列
        Collections.shuffle(list);
        //3) sort(list) 对list进行排序 需要实现compareTo方法
        Collections.sort(list);
        //4) swap(list,i,j) 对list中的i处的元素和j处的进行交换
        Collections.swap(list,0,3);
        //5) max(Collection) 返回Collection中最大的元素(基于compareTo方法)
        //6) min(Collection) 返回Collection中最小的元素(基于compareTo方法)
        //7) frequency(Collection,i) 返回Collection中i出现的次数
        int frequency = Collections.frequency(list, 55);
        //8) copy(list dest,list src) 把src的内容复制到dest中
        // 应该先新建一个带src.size()个数null的一个list
        List<Object> dest = Arrays.asList(new Object[list.size()]);
        Collections.copy(dest,list);
        // 9) 利用synchronizedList(list)方法 将list转换为线程安全的
        List<Integer> list1 = Collections.synchronizedList(list);
    }
}

Collection和Collections的区别

  • java.util.Collection 是一个集合接口(集合类的一个顶级接口)。它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。Collection接口的意义是为各种具体的集合提供了最大化的统一操作方式。
  • Collections则是集合类的一个工具类/帮助类,其中提供了一系列静态方法,用于对集合中元素进行排序、搜索以及线程安全等各种操作。

List接口

实现List接口的集合是有序的、可重复的。

List接口主要有四个实现类: 分别是ArrayList、Vector、LinkedList和CopyOnWriteArrayList

常用方法

1.操作元素

  • 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集合继承过来的。

2.判断元素

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

3.查询元素

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

4.其它

  • iterator():返回迭代器(Iterator)对象,迭代器对象用于遍历集合。该方法是从Collection继承过来的。
  • size():返回List集合中的元素数,返回值是int类型。该方法是从Collection集合继承过来的。
  • subList(int fromIndex, int toIndex):返回List集合中指定的 fromIndex(包括 )和 toIndex(不包括)之间的元素集合,返回值为List集合。

遍历集合

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

  • 使用for循环遍历:List集合可以使用for循环进行遍历,for循环中有循环变量,通过循环变量可以访问List集合中的元素。
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
  • 使用for-each循环遍历:for-each循环是针对遍历各种类型集合而推出的,笔者推荐使用这种遍历方法。
for (Object o : list) {
    System.out.println(o);
}
  • 使用迭代器遍历:Java提供了多种迭代器,List集合可以使用Iterator和ListIterator迭代器。
//获取迭代器
Iterator iterator = list.iterator();
//判断是否还有元素
while(iterator.hasNext()){
   System.out.println(iterator.next());
}

:使用for-each循环遍历和使用迭代器遍历从集合中取出的元素都是Object类型。

ListIterator和Iterator的区别

  • Iterator可以遍历Set 和 List 集合,而ListIterator只能用于遍历List。
  • Iterator和ListIterator都可实现删除元素,但是ListIterator可以实现遍历时对元素的修改,用set()方法实现。Iterator仅能遍历,不能修改。
  • Iterator只能单向遍历 [ hasNext()、next()方法)] ,而ListIterator可以双向遍历(向前/后遍历) [ 从后往前 hasPrevious()、previous()方法 ]
  • ListIterator接口继承于Iterator接口,然后添加了一些额外的功能,比如添加一个元素、替换一个元素、获取前面或后面元素的索引位置。

Set接口

常用方法

1.操作元素

  • add(Object element):在Set集合的尾部添加指定的元素。该方法是从Collection集合继承过来的。
  • remove(Object element):如果Set集合中存在指定元素,该方法是从Collection集合继承过来的。
  • clear():从Set集合中移除所有元素。该方法是从Collection集合继承过来的。

2.判断元素

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

3.其他

  • iterator():返回迭代器(Iterator)对象,迭代器对象用于遍历集合。该方法是从Collection集合继承过来的。
  • size():返回Set集合中的元素数,返回值是int类型。该方法是从Collection集合继承过来的。

Set和List的区别

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

Map接口

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

常用方法

1.操作元素

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

2.判断元素

  • isEmpty():判断Map集合中是否有键值对,没有返回true,有返回false。
  • containsKey(Object key):判断键集合中是否包含指定元素,包含返回true,不包含返回false。
  • containsValue(Object value):判断值集合中是否包含指定元素,包含返回true,不包含返回false。

3.查看集合

  • keySet():返回Map中的所有键集合,返回值是Set类型。
  • values():返回Map中的所有值集合,返回值是Collection类型。
  • size():返回Map集合中键值对数。

Map与Set、List的关系

1)Map集合与Set集合的关系:如果把Map里的所有key放在一起看,他们就组成了一个Set集合(所有的key没有顺序,key与key之间不能重复),实际上Map确实包含了一个keySet()方法,用户返回Map里所有key组成的Set集合。

2)Map集合与List集合的关系:如果把Map里的所有value放在一起来看,它们又非常类似于一个List:元素与元素之间可以重复,每个元素可以根据索引来查找,只是Map中索引不再使用整数值,而是以另外一个对象作为索引。

Queue

Queue用于模拟队列这种数据结构。队列通常是指“先进先出(FIFO)”的容器。队列的头部保存在队列中存放时间最长的元素,尾部保存存放时间最短的元素。新元素插入到队列的尾部,取出元素会返回队列头部的元素。通常,队列不允许随机访问队列中的元素。

PriorityQueue

优先队列采用堆这种数据结构,元素可以按照任意顺序插, 但是删除的时候总是会删除最小的那个。优先队列主要用于任务调度,当启动新任务时会把优先级最高的任务从队列中删除(习惯上优先级最高的是1)。这里添加的对象(元素)需要实现compareTo方法。

public class PriorityQueueTest {
    @Test
    public void test1() {
        var pq = new PriorityQueue<LocalDate>();
        pq.add(LocalDate.of(2021, 7, 1));
        pq.add(LocalDate.of(2021, 8, 18));
        pq.add(LocalDate.of(2021, 9, 20));
        // 调用remove时会把元素中最小的那个删除掉
        pq.remove();
        System.out.println(pq); //output:[2021-07-01, 2021-09-20]
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,047评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,807评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,501评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,839评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,951评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,117评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,188评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,929评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,372评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,679评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,837评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,536评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,168评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,886评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,129评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,665评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,739评论 2 351

推荐阅读更多精彩内容