2021-05-16

2021-05-15

集合框架使用集合做什么集合的分类具体的实现类ListArrayListLinkedListSetTreeSetMapHashMapTreeMap数组、List、Set、Map的数据转换数组转 List数组和Set从Map中得到Set和List散列表(哈希表)的基本原理散列表是如何根据Key来快速找到它所匹配的 Value 呢 ?散列表的读写操作写操作(put)读操作(get)IteratorCollections排序查找排序List 集合排序TreeMap 排序自定义类排序外部指定排序本身拥有排序


集合框架

程序开发并不是解决了业务的基本功能就完成了,很多时候程序运行的环境是有限制的。比如内存小,CPU频率低,或者是像手机这样的设备,能源供应有限。在这种环境下,就需要程序能够在有限的环境中提升效率。这就需要使用数据结构和算法。


但是数据结构与算法即便是学过,也未必在工作时能够用好,而且通用性、性能等等也都是问题。加上学习程序开发的受众群体越来越广,让程序员全部自己实现数据结构与算法不是一个好的主意。所以现在很多语言为了能够提升学习效率,降低学习门槛,同时也为了让程序有更好的执行效率和通用性,就自带了各种实现了数据结构与算法的API集合。在Java中,这就是我们现在要学习的「集合框架」


与现在常见到的数据结构类库一样,Java也是将集合类库的接口(interface)与实现(implementation)分离。所以我们的学习方式一般都是先搞明白接口的分类和关系,然后根据不同的接口来学习对应的实现类。


使用集合做什么

搬运数据,集合可以存储数据,然后通过API调用很方便就可以传递大量数据


数据处理,集合中可以直接对数据进行操作,比如统计、去重


排序,可以将数据按照需求进行各种排序,然后再传递给调用者


集合的分类

image-20200212141927241.png

Java的集合从 Collection 接口和 Map 接口入手


Map 接口和 Collection 没有交集,它有自己的方式,只要标准库后缀不是Map 结尾的,都是直接或者间接实现了Collection接口。


Collection 接口中常见的操作是数据的添加、删除


add / addAll


remove / removeAll / removeIf


借助 Iterator 接口,Collection 还具备了数据的循环


public interface Collection<E> extends Iterable<E>{

//...

// 对数据循环

Iterator<E> iterator();

}


通过 Iterable 接口, 标准库中的集合都可以使用 forEach 循环。


具体的实现类

集合类型 描述

ArrayList 一种可以动态增长和缩减的索引序列

LinkedList 一种可以在任何位置进行高效地插人和删除操作的有序序列

ArrayDeque 一种用循环数组实现的双端队列

HashSet 一种没有重复元素的无序集合

TreeSet 一种有序集

EnumSet 一种包含枚举类型值的集

LinkedHashSet 一种可以记住元素插人次序的集

PriorityQueue 一种允许高效删除最小元素的集合

HashMap 一种存储键/ 值关联的数据结构

TreeMap 一种键值有序排列的映射表

EnumMap 一种键值属于枚举类型的映射表

LinkedHashMap 一种可以记住腱/ 值项添加次序的映射表

WeakHashMap 一种其值无用武之地后可以被垃圾回收器回收的映射表

IdentityHashMap 一种用 == 而不是用equals 比较键值的映射表

Collection

image-20200212145950872.png

Map


image-20200212150240334.png

虽然类很多 ,但是我们在教授中只需要交几个类就可以了,分别是下面:


ArrayList


LinkedList


HashSet


HashMap


TreeMap


然后加上工具类2个:


Collections


Arrays


List

有序集合,可以精确控制列表中每个元素的插入位置。通过整数索引获取列表中的元素。List允许出现重复的值 , 并可以精确控制列表中每个元素的插入位置,通过整数索引获取列表中的元素。


方法名 说明

add(E e) 增加单个数据

addAll(Collection<? extends E> c) 将一个 Collection 集合的数据添加到现在的集合中

remove(Object o) 删除指定的元素

contains(Object o) 判断集合是否包含指定的元素

size() 得到集合的数据总数

isEmpty() 判断集合是否有数据

get(int index) 通过索引获取对应的数据元素

set(int index, E element) 通过索引和新的元素替换原有内容

clear() 清空数据

toArray() 将List转为对象数组

ArrayList

ArrayList 是List 接口的大小可变数组的实现。实现了所有可选列表操作, 并允许包括null 在内的所有元素。除了实现List 接口外, 此类还提供一些方法来操作内部用来存储列表的数组的大小( 此类大致上等同于 vector 类, 但 vector 是同步的) 。


ArrayList 的底层是使用数组实现的,看下面的图


image-20200212171434134.png

可以看到,数组中的每一个元素,都存储在内存单元中,并且元素之间紧密排列,既不能打乱元素的存储顺序,也不能跳过某个存储单元进行存储。


ArrayList 底层既然是使用数组实现,那么特点就和数组一致:查询速度快,增删速度慢。


每个ArrayList 实例都有一个容量。该容量是指用来存储列表元素的数组的大小, 它总是至少等于列表的大小。随着向Array L ist 中小断添加元素, 其容量也自动增长。并未指定增长策略的细节,因为这不只是添加元素会带来分摊固定时间开销那样简单。我们可以使用默认构造函数创建容量为 10 的列表, 也可以初始化指定容量大小。


ArrayList 指定初始容量大小的构造器方法


public ArrayList(int initialCapacity) {

if (initialCapacity > 0) {

this.elementData = new Object[initialCapacity];

} else if (initialCapacity == 0) {

this.elementData = EMPTY_ELEMENTDATA;

} else {

throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity);

}

}


常用的操作


public static void main(String[] args) {

ArrayList<Integer> list = new ArrayList<>();


    //  添加数据

    list.add(123);

    list.add(346);


    //  替换数据

    list.set(1, 777);


    //  将list中的所有数据放到 list2 中

    List<Integer> list2 = new ArrayList<>();

    list2.addAll( list );


    //  循环list2中所有的数据

    for (Integer integer : list2) {


        System.out.println( integer );


        //  删除循环出的对象

        list2.remove(integer);

    }


    //  list 集合是否有数据

    if( !list.isEmpty() ) {


        System.out.println("list.size = "+ list.size());


        //  清空 list

        list.clear();

    }


    //  在清空list后,再看list现在有多少数据

    System.out.println("list.size = "+ list.size());

}


}

LinkedList

LinkedList 是一个链表结构,可当作堆栈、队列、双端队列 。链表是一种在物理上非连续、非顺序的数据结构,由若干节点(node)所组成。


单链表

image-20200212173413313.png

单向链表的每一个节点包含两部分,一部分是存放数据的变量data,另一部分是指向下一个节点的指针next。正如地下党的联络方式,一级一级,单线传递:

private static class Node {

int data;

Node next;

}


双链表


双向链表比单向链表稍微复杂一些,它的每一个节点除了拥有data和next指针,还拥有指向前置节点的prev指针



image-20200212173517719.png

和数组不同,链表存储数据的时候,则采用了见缝插针的方式,链表的每一个节点分布在内存的不同位置,依靠next指针关联起来。这样可以灵活有效地利用零散的碎片空间。



image-20200212173548104.png

LinkedList 做数据的添加和删除操作时速度很快,但是做查询的时候速度就很慢,这和 ArrayList 刚好相反。


适用 LinkedList 独有的方法,在集合前后做数据插入


public static void main(String[] args) {

LinkedList<Integer> list = new LinkedList<>();


    list.add(123);

    //  添加相同的数据

    list.add(123);

    list.add(456);

    list.add(789);

    list.add(101);


    //  将数据 111 添加到 list 的末尾

    list.addLast(111);

    //  将数据 999 添加到 list的最前面

    list.addFirst(999);


    for (int i = 0; i < list.size(); i++) {

        System.out.println( list.get(i) );

    }


}

注意代码中声明和实现都是 LinkedList , 如果声明的是 List 接口 , addFirst 和 addLast 方法是不可见的


Set

Set 的特点是去重,如果相同的数据只会保留一个。集合内的数据是一个无序的状态,。当然也有例外,TreeSet就是有序的。


方法名 说明

add(E e) 增加单个数据

addAll(Collection<? extends E> c) 将一个 Collection 集合的数据添加到现在的集合中

remove(Object o) 删除指定的元素

contains(Object o) 判断集合是否包含指定的元素

size() 得到集合的数据总数

isEmpty() 判断集合是否有数据

clear() 清空数据

toArray() 将List转为对象数组

可以看到,Set 和 List 中的方法都是相同的,作用也一致。但是 Set 是没有直接获取数据的方法。我们更多的时候使用的是 List 和 Map。


Has

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容

  • Collection 接口和 Collections 类都是做什么用的 ?Collection是集合类的顶级接口。...
    王舒畅阅读 100评论 0 1
  • Collection 接口和 Collections 类都是做什么用的 ?Collection:集合的抽象数据类型...
    04d66c630228阅读 93评论 0 0
  • 集合框架使用集合做什么集合的分类具体的实现类ListArrayListLinkedListSetTreeSetMa...
    han741阅读 245评论 0 1
  • Collection 接口和 Collections 类都是做什么用的 ?Collection:是集合类的上层接口...
    屈浩宇阅读 271评论 0 0
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,520评论 28 53