Java基础-集合类-概述

Java工程师知识树 / Java基础


1.为什么要用集合类

Java编程思想中指出:

通常,程序总是根据运行时才知道的某些条件去创建新对象。
在此之前,不会知道所需对象的数量,甚至不知道确切的类型。
为解决这个普遍的编程问题,需要在任意时刻和任意位置创建任意数量的对象。
所以,就不能依靠创建命名的引用来持有每一个对象:
MyType aReference;
因为你不知道实际上会需要多少这样的引用。
大多数语言都提供某种方法来解决这个基本问题。Java有多种方式保存对象(应该说是对象的引用)。例如前面曾经学习过的数组,它是编译器支持的类型。数组是保存一组对象的最有效的方式,如果你想保存一组基本类型数据,也推荐使用这种方式。但是数组具有固定的尺寸, 而在更一般的情况中,你在写程序时并不知道将需要多少个对象,或者是否需要更复杂的方式来存储对象,因此数组尺寸固定这一限制显得过于受限了。
Java实用类库还提供了一套相当完整的容器类来解决这个问题。
其中基本的类型是List、Set、Queue和Map。这些对象类型也称为集合类,但由于Java的类库中使用了Collection这个名字来指代该类库的一个特殊子集,所以我使用了范围更广的术语“容器”称呼它们。

解读:

  1. Java保存对象的方式有:

    • 数组【可以保存基本类型数据;数组尺寸固定;只能存储同一种类型的对象】

    • 集合类【不可以保存基本类型数据;在根本上都是数组,只是可以动态改变数组的大小;结合泛型可以存储多种类型的对象】

  2. Java中的容器指Collection、Map的统称

  3. 容器中存储的是对象的引用不是对象的值;数组在存储基本数据类型时是存储的对象的值

  4. 为什么使用集合? 可以封装一组对象的操作,降低编程难度,增加代码复用性,提高程序运行速度与质量。

2.集合中的概念

Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念:

    1. Collection。一个独立元素的序列,这些元素都服从一条或多条规则。List必须按照插入的顺序保存元素,而Set不能有重复元素。Queue按照排队规则来确定对象产生的顺序(通常与它们被插入的顺序相同)。
    1. Map。一组成对的“键值对”对象,允许你使用键来査找值。ArrayList允许你使用数字 来査找值,因此在某种意义上讲,它将数字与对象关联在了一起。映射表允许我们使用另一个 对象来査找某个对象,它也被称为“关联数组”,因为它将某些对象与另外一些对象关联在了一 起,或者被称为“字典”,因为你可以使用键对象来査找值对象,就像在字典中使用单词来定义 一样。Map是强大的编程工具。

什么是集合框架?

集合框架是一个代表、操作集合的统一架构。所有的集合框架都包含以下几点:

  • 接口:表示集合的抽象数据类型。接口允许我们操作集合时不必关注具体实现,从而达到“多态”。在面向对象编程语言中,接口通常用来形成规范。

  • 实现类:集合接口的具体实现,是重用性很高的数据结构。

  • 算法:用来根据需要对实体类中的对象进行计算,比如查找,排序。 同一种算法可以对不同的集合实现类进行计算,这是利用了“多态”。重用性很高。

3.集合的分类

整体体系图

Collection接口及其常用实现

Collection接口及其常用实现

Map接口及其常用实现

Map接口及其常用实现

附带Java集合最全结构展示图

4.常用集合类与对应数据结构

集合类是Java数据结构的实现。所以,从数据结构层面对比下集合类。

集合 接口/类 说明
Collection 接口 定义了集合的基本方法,
List 接口 元素有序,元素可重复。主要实现类:ArrayList,LinkedList,Vector。
Vector 线性表的数组实现
Stack 栈,Last in first out,继承自Vector
ArrayList 动态数组,源码底层维护着List的容量与实际长度
LinkedList 双向链表,此外它还实现了Deque,即也实现了Queue
Queue 接口 队列,First in first out
Deque 接口 双向队列,Deque继承自Queue,并增加了首尾两端的进出队列操作
Map 接口 一组元素结构为K、V型的集
HashMap 哈希数组+链表,通过哈希函数能够快速地找到元素,无冲突的情况下仅需访问一次 ;1.8后哈希数组+链表+红黑树
HashTable HashTable与HashMap的区别是其线程安全,同时它不允许K、V为null
TreeMap Map的二叉平衡树实现,根据K的hashcode排序
ConcurrentHashMap 线程安全的HashMap,HashTable的替代者
Set 接口 元素无序,元素不重复。主要实现类:HashSet,TreeSet,LinkedHashSet。
HashSet 内部使用HashMap实现,K对应E,V保存了一个Object
TreeSet 内部由TreeMap实现,K对应E,V保存了一个Object
LinkedHashSet 哈希表和链表的结合,且是一个双向链表;不重复且同时具有可预测的迭代顺序

5.容器操作使用

Collection增删改查与遍历

作为集合的一个根接口,定义了一组对象和它的子类可以实现的方法:


Collection.png

对集合的基础操作,比如 :

int size() 获取元素个数

boolean isEmpty() 是否个数为 0

boolean contains(Object element) 是否包含指定元素

boolean add(E element) 添加元素,成功时返回 true

boolean remove(Object element) 删除元素,成功时返回 true

Iterator<E> iterator() 获取迭代器

还有一些操作整个集合的方法,比如 :

boolean containsAll(Collection<?> c) 是否包含指定集合 c 的全部元素

boolean addAll(Collection<? extends E> c) 添加集合 c 中所有的元素到本集合中,如果集合有改变就返回 true

boolean removeAll(Collection<?> c) 删除本集合中和 c 集合中一致的元素,如果集合有改变就返回 true

boolean retainAll(Collection<?> c) 保留本集合中 c 集合中两者共有的,如果集合有改变就返回 true

void clear() 删除所有元素

还有对数组操作的方法:

Object[] toArray() 返回一个包含集合中所有元素的数组

<T> T[] toArray(T[] a) 返回一个包含集合中所有元素的数组,运行时根据集合元素的类型指定数组的类型

在 JDK 8 以后,Collection 接口还提供了从集合获取连续的或者并行流:

Stream<E> stream()

Stream<E> parallelStream()

List接口与Set接口实现Collection接口常用的方法有:

List接口
        List接口下的集合元素存储有序,可以重复。
        List的特有功能
          A:添加功能
              void add(int index, Object obj):在指定位置添加元素
          B:删除功能
              Object remove(int index):根据指定索引删除元素,并把删除的元素返回。
          C:修改功能
              Object set(int index, Object obj):把指定索引位置的元素修改为指定的值,返回修改前的值。
          D:获取功能
              int indexOf(Object o):返回指定元素在集合中第一次出现的索引
              Object get(int index):获取指定位置的元素
              ListIterator listIterator():列表迭代器
          E:截取功能
              List subList(int fromIndex, int toIndex):截取集合。

  Set 接口
          Set接口下的元素无序,不可以重复。其下面常用有HashSet和TreeSet。
          HashSet
           底层数据结构是哈希表,线程不安全,效率高。
           保证唯一性依赖两个方法:hashCode()和equals()。
           顺序:
                   判断hashCode()值是否相同。
                   相同:继续走equals(),看返回值
                               如果true:就不添加到集合。
                               如果false:就添加到集合。
                   不同:就添加到集合。
          TreeSet
            底层数据结构是二叉树,线程不安全,效率高。
            保证元素唯一性的方法时根据返回值是否是0。
            保证排序的两种方式:
                    自然排序(元素具备比较性):实现Comparable接口
                    比较器排序(集合具备比较性):实现Comparator接口

遍历 Collection 的几种方式:

for-each语法
Collection<Person> persons = new ArrayList<Person>();
for (Person person : persons) { 
    System.out.println(person.name);  
}  
使用 Iterator 迭代器
Collection<Person> persons = new ArrayList<Person>();
Iterator iterator = persons.iterator();
while (iterator.hasNext) { 
    System.out.println(iterator.next);  
}  
使用 aggregate operations 聚合操作
Collection<Person> persons = new ArrayList<Person>();
persons
    .stream()
    .forEach(new Consumer<Person>() {  
        @Override  
        public void accept(Person person) {  
            System.out.println(person.name);  
        }  
}); 

Map增删改查与遍历

map是一个键值对形式的集合。它的元素都是有键和值组成。Map的键(key)是唯一的,值(value)可以重复。

Map的功能:

A:添加功能
V put(K key ,V value) :当key在集合中不存在是,添加元素;当key存在时替换元素

B:判断功能
boolean containsKey (Object key) :判断指定的键是否在集合中存在
Boolean containsValue(Object value):判断指定的值是否在集合中存在
Boolean isEmpty() :判断集合是否为空

C:删除功能
Void clear():清除所有键值对数据

D:获取功能
Object get (Object key) :根据键获取值
Set<K> keyset(): 所有键的集合
Collection<V>values() :所有值的集合

E:长度功能
Int size()

Map常用的有HashMap、HashTable和TreeMap,遍历常用有3种方法:

Map<String, Object>map = new HashMap<String, Object>();
map.put(“test1”, object1);
……
map.put(“testn” , objectn);

(1).Map的values()方法可以获取Map值的集合:

Iterator it = map.values().iterator(); 
while(it.hasNext()){ 
  Object obj = it.next(); 
} 

(2).Map的keySet方法可以获取Map键的Set集合:

Set<String> keys = map.keySet(); 
for(Iterator it = key.iterator(); it.hasNext(); ){ 
  String key = it.next(); 
  Object obj = map.get(key); 
} 

(3).通过Map.entrySet使用iterator遍历key和value

Iterator<Map.Entry<Integer, String>> it = map.entrySet().iterator();
while (it.hasNext()) {
     Map.Entry<Integer, String> entry = it.next();
     System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}

(4).通过Map.entrySet遍历key和value,推荐,尤其是容量大时

for (Map.Entry<Integer, String> entry : map.entrySet()) {
    //entry.getKey() ;entry.getValue(); 
    System.out.println("key= " + entry.getKey() + " and value= " + entry.getValue());
}

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

推荐阅读更多精彩内容