全部章节   >>>>


本章目录

7.1 集合概述

7.1.1 Java集合体系概述

7.1.2 实践练习

7.2 List集合

7.2.1 ArrayList实现类

7.2.2 LinkedList实现类

7.2.3 实践练习(一)

7.2.4 实践练习(二)

7.3 Set集合和Iterator迭代器

7.3.1 Set集合

7.3.2 Iterator迭代器

7.3.3 实践练习

7.4 Map集合

7.4.1 Map集合

7.4.2 实践练习

总结:


7.1 集合概述7

7.1.1 Java集合体系概述

为了使程序方便地存储和操纵数目不固定的一组数据,JDK类库中提供了Java集合,所有Java集合类都位于java.util包中。与Java数组不同,Java集合不能存放基本数据类型,而只能存放对象。

Java集合类主要由两个接口派生而出,即CollectionMap接口。Collection和Map是Java集合框架的最上层的父接口,这两个接口又包含其他的子接口和实现类。

Java集合主要包括三种类型: Set(集),List(列表),Map(映射)。

Collection集合体系的继承树

实线表示继承关系,虚线表示实现关系

Map体系的继承树

Java集合的三种数据类型存储示意图

1、Set特点

类似于一个罐子,将一个对象添加到Set集合时,Set集合无法记住添加此元素的顺序

Set集合中的元素是不能重复的,否则系统无法准确识别此元素。

2、List特点

类似于一个数组,它可以记录每个元素添加的顺序,但List长度可变。

3、Map特点

Map集合的存放方式,同样类似于一个罐子,但Map集合中的每项数据都由两个值组成。它们分别为key和value,key不可以重复,但是value可以重复。

Collection接口常用方法

方法名

说明

boolean add(Object obj)

向集合中添加一个元素

boolean addAll(Collection c)

将集合c的所有元素添加到指定集合中

void clear()

清除集合中的所有元素,此时集合长度变为0

boolean contains(Object obj)

返回集合中是否包含指定的元素

boolean contains(Collection c)

返回集合中是否包含指定的c集合

Boolean  isEmpty()

判断集合是否为空。集合长度为0时返回true,否则返回false

Iterator iterator()

返回一个Iterator对象,用于遍历集合中的元素

boolean remove(Object obj)

删除集合中的指定元素obj,当集合中包含一个或多个元素obj时,仅删除第一个符合条件的元素

int  size()

返回集合中元素的个数

Object[] toArray()

将当前集合转换成一个Object[]类型的数组

7.1.2 实践练习

7.2 List集合

List集合代表一个元素是有序的、且可以重复的、可以为null的集合。

集合中每个元素都有其对应的顺序索引,List集合允许添加重复元素,可以通过索引来访问指定位置的集合元素。

List 的数据结构就是一个序列,存储内容时直接在内存中开辟一块连续的空间,然后将空间地址与索引对应。

List最常见的实现类是ArrayList和LinkedList。

除Collection接口的所有方法之外List还拥有的其他方法

方法名

说明

void add(int index, Object element)

添加对象element到位置index上

booleanaddAll(int index, Collection collection)

在index位置后添加容器collection中所有的元素

Object get(int index)

取出下标为index的位置的元素

intindexOf(Object element)

查找对象element在List中第一次出现的位置

intlastIndexOf(Object element)

查找对象element在List中最后出现的位置

Object remove(int index)

删除index位置上的元素,并返回被删除的这个元素

Object set(int index,Object element)

将index位置上的所示对象替换为element并返回被替换

7.2.1 ArrayList实现类

ArrayList是基于数组实现的List类,ArrayList底层是通过一个长度可变的数组实现的。

ArrayList允许对元素进行快速的随机访问,但是向ArrayList中插入与删除元素的速度较慢。

示例: 演示ArrayList类使用方法

//创建ArrayList对象
ArrayList arrayList=new ArrayList();
arrayList.add("JAVA-DEMO");//向集合中添加字符串对象
arrayList.add(new Hero());//向集合中添加用户自定义对象
System.out.println("arrayList集合的大小="+arrayList.size());
for(int i=0;i<arrayList.size();i++) //遍历集合元素
Object obj=arrayList.get(i); //按照下标获取元素
boolean flag=arrayList.contains("JAVA-DEMO"); //是否包含字符串"JAVA-DEMO"
Object obj=arrayList.remove("JAVA-DEMO");//删除指定元素字符串"JAVA-DEMO"
System.out.println("被删除的元素="+obj);
arrayList.set(0, "ANDROID");//将集合下标为0的元素修改为ANDORID

7.2.2 LinkedList实现类

LinkedList类在实现时,采用链表数据结构,所以向LinkedList中插入和删除元素的速度较快,随机访问速度则相对较慢(随机访问是获取指定下标位置的元素)

LinkedList单独具有addFirst()、addLast()、getFirst()、getLast()、removeFirst()和removeLast()方法。这些方法使LinkedList可以作为堆栈、队列和双向队列来使用。

LinkedList常用方法

方法名

说明

void addFirst(Object o)

将指定元素o插入列表起始位置

addLast(Object o)

将指定元素o添加至列表末尾处

Object removeFirst()

移除并返回列表的首元素

Object removeLast()

移除并返回列表的首末元素

示例:演示LinkedList类使用方法

LinkedList linkedList=new LinkedList();
ArrayList ayList=new ArrayList();
ayList.add("JAVA-DEMO");
ayList.add('中');
//将ayList对象添加至linkedList集合中
linkedList.add(ayList);
//添加自定义类型对象
linkedList.add(new Hero());
linkedList.addFirst(99.8);//向集合头部添加一个元素
Object obj=linkedList.removeFirst();//删除头部元素

示例:比较ArrayList与LinkedList删除元素的效率

ArrayList aList=new ArrayList(); //创建ArrayList集合
System.out.println("==========ArrayList==========");
long bTime=System.currentTimeMillis(); //获取当前系统的时间(毫秒数表示)
System.out.println("起始时间:"+bTime);
for(int i=0;i<100000;i++)
aList.add("DEMO"+i);//向集合中添加数据
int size=aList.size();
for(int i=0;i<size;i++)
aList.remove(0);//每次都删除集合中的第一个元素
long eTime=System.currentTimeMillis();
System.out.println("结束时间:"+eTime);
System.out.println("ArrayList添加、删除所用时间="+(eTime-bTime)+"毫秒");
//创建LinkedList集合
LinkedList lList=new LinkedList();
...
System.out.println("LinkedList添加、删除所用时间="+(edTime-bginTime)+"毫秒");

示例:比较ArrayList与LinkedList访问元素的效率

ArrayList aList=new ArrayList(); //创建ArrayList集合
System.out.println("==========ArrayList==========");
for(int i=0;i<100000;i++)
aList.add("DEMO"+i);//向集合中添加数据
//获取当前系统的时间(毫秒数表示)
long bTime=System.currentTimeMillis();
System.out.println("开始时间:"+bTime);
for(int i=0;i<1000000000;i++)
aList.get(99999); //每次读取列表末尾元素
long eTime=System.currentTimeMillis();
System.out.println("结束时间:"+eTime);
System.out.println("ArrayList随机访问所用时间="+(eTime-bTime)+"毫秒");
LinkedList lList=new LinkedList(); //创建LinkedList集合
System.out.println("==========LinkedList==========");
...
for(int i=0;i<1000000000;i++)
lList.get(99999); //每次读取列表末尾元素
...
System.out.println("LinkedList随机访问所用时间="+(edTime-bgTime)+"毫秒");

经验:

List就是一个线性表接口,而ArrayList、LinkedList又是线性表的两种典型实现,ArrayList   是基于数组的线性表,而LinkedList是基于链表的线性表。

当对集合元素进行频繁的添加或删除操作时,使用LinkedList效率比较高,因为链表的插入和删除操作效率比较高。

当对集合元素进行频繁的读取操作时,使用ArrayList效率比较高,因为基于数组的线性表的随机访问效率比较高。

7.2.3 实践练习(一)

7.2.4 实践练习(二)

7.3 Set集合和Iterator迭代器

7.3.1 Set集合

Set集合,类似于一个瓶子,“装进”Set集合中的多个对象之间没有明显的顺序。

Set集合不允许包含相同的元素,如果试图将两个相同的元素加入同一个Set集合中,则添加操作失败返回false,且新元素不会被加入其集合中。

HashSet是Set接口的最常用的实现类。HashSet按Hash算法实现存储集合中的元素,因为其具有良好的存储和查找性能。

Set的排列顺序可能与添加顺序不同,Set元素值可以是null。

示例:添加Cat对象到HashSet集合

public class Cat {
private String name;
private String color;

public String toString(){ //重新toString()
return "名字:"+this.name+"-"+"毛色:"+this.color;
}
}
public class HashSetTest {
public static void useHashSet(){
HashSet hs=new HashSet();
hs.add("JAVA");
hs.add(new Cat("加菲","黄色"));
hs.add(new Cat("汤姆","青色"));
hs.add(new Cat("加菲","黄色"));
hs.add("JAVA");//添加重复对象"JAVA"
hs.add(100);//添加重复对象"JAVA"
System.out.println("HashSet对象集合="+hs);
}
…..

提问:有两条猫的名字和颜色一摸一样,怎么它们可以一起添加到Set集合?

分析:

这两条猫的名字和颜色一摸一样,但它们equals()返回值为false,hashCode()值也不相等。所以这两条猫不相同。

如果两条猫相同的逻辑是它们名字和颜色相同,则可通过重写Cat类的equals() 和hashCode() 。

示例:重写Cat的equals() 和hashCode()

public  boolean  equals(Object obj){
if(obj==this){
return true;
}else{
if(obj instanceof Cat){
Cat cat=(Cat)obj;
if(this.name.equals(cat.name) && this.color.equals(cat.color))
return true;
else
return false;
}else
return false;
}
}
//重写hashCode()方法
public int hashCode(){
return this.name.hashCode()*this.color.hashCode();
}

重写hashCode()方法的一般规则如下:

在程序运行时,同一个对象的hashCode()方法应该返回相同的值。

当两个对象通过equals()方法比较返回true时,这两个对象的hashCode()方法应返回相等的值。

象中用作equals()方法比较标准的属性,都应该用于计算hashCode的值。

7.3.2 Iterator迭代器

Iterator接口隐藏了各种Collection实现类的底层细节,该接口提供了遍历Collection集合元素的统一编程接口。

迭代器是一种设计模式,它是一个对象,它可以遍历并选择序列中的对象,而开发人员不需要了解该序列的底层结构。迭代器通常被称为“轻量级”对象,因为创建它的代价小。

由于Set集合中存储的是无序的元素,因此无法在循环中按照下标获取Set集合中的元素,所以利用Iterator接口遍历Set集合中的元素尤为方便。

Iterator常用方法

方法名

说明

boolean hasNext(Object o)

如果被迭代的集合中的元素没有遍历完成,则返回true

Object next()

返回集合中的下一个元素

Void remove()

将迭代器新返回的元素删除

示例:Iterator迭代器应用案例

HashSet  hs=new HashSet();
hs.add(1);
hs.add(new Date());
hs.add("ANDORID");
hs.add(new Cat("加菲","粉色"));
//调用HashSet对象的iterator()方法,返回Iterator实例
Iterator it=hs.iterator();
//使用while循环,循环判断迭代器中是否还有元素
System.out.println("====使用迭代器遍历HashSet集合=====");
while(it.hasNext()){
//获取迭代器中的数据
Object obj=it.next();
System.out.println(obj);
}

7.3.3 实践练习

7.4 Map集合

Map用于保存具有映射关系的数据。Map集合中保存着两组值,一组值用于保存Map里的key,另外一组值保存Map的value。key和value可以为null。

key和value可以是任意类型的数据。Map的key不允许重复,即同一个Map对象的任何两个key通过equals()方法比较总是返回false。

key和value间存在单向一对一关系,即通过指定的key总能找到唯一的、确定的value。从Map中取出数据时,只要给出指定的key,就可以取出对应的value。

HashMap是Map接口最为常用的实现类,HashMap通过哈希码对其内部的映射关系进行快速查找。

7.4.1 Map集合

Map接口常用方法

方法名

说明

put(K key,V value)

向映射中添加一对key与value的映射关系

Object get(Object key)

返回映射中key所对应的value。如果该映射中不包含key,则返回null

putAll(Map  map)

将映射map所有的键值映射关系添加到当前映射

containsKey(Object key)

如果此映射包含指定键的映射关系,则返回true

containsValue(Object value)

如果此映射将一个或多个键映射到指定的value,则返回true

keySet()

将该集合中的所有键对象以Set集合的形式返回

values()

将该集合中的所有值对象以Collection集合的形式返回

remove(Object key)

如果存在指定的键key,则移除该键的映射关系,并返回与该键对象对应的值对象,否则返回null

clear()

从此映射中移除所有映射关系

isEmpty()

如果此映射未包含键-值映射关系,则返回true

size()

返回此映射中的键-值映射关系的数量

示例:HashMap应用案例

Map hm=new HashMap();
hm.put("JAVA", "DEMO");
hm.put("中国", "北京");
hm.put(1, "one");
hm.put(true,"正确" );
hm.put("中国", "上海");
System.out.println("========HashMap集合添加元素后=======");
System.out.println(hm);
System.out.println("====按照Kye获取对应Value值====");
Object value=hm.get("中国");
System.out.println("key值为中国对应的value值="+value);
System.out.println("HashMap集合的大小="+hm.size());
System.out.println("===遍历HashMap集合===");
//返回存储HashMap集合中的所有的key(键)的Set集合
Set set=hm.keySet();
Iterator it=set.iterator();//返回key集合的Iterator迭代器
while(it.hasNext()){//遍历key
Object key=it.next();//得到HashMap集合中的key值
Object val=hm.get(key);//通过key得到对应的value值
System.out.println("键="+key+"\t"+"值="+val);
}

HashMap与Hashtable的区别

HashMap

Hashtable

允许出现空值、空键

不允许出现空值、空键

线程异步,效率较高

线程同步,效率较低

继承自AbstractMap

继承自Dictionary

7.4.2 实践练习

总结:

  • 所有Java集合类都位于java.util包中。与Java数组不同,Java集合不能存放基本数据类型,而只能存放对象。
  • Java集合类主要由两个接口派生而出,即Collection和Map接口。Collection和Map是Java集合框架的最上层的父接口,这两个接口又包含其他的子接口和实现类。
  • List集合代表一个元素是有序的、且可以重复的、可以为null的集合。可以通过get(int index)取出下标为index的元素。
  • List最常见的实现类是ArrayList和LinkedList。当对集合元素进行频繁的读取操作时,使用ArrayList效率比较高;当对集合元素进行频繁的添加或删除操作时,使用LinkedList效率比较高。
  • Set集合不允许包含相同的元素,Set的排列顺序可能与添加顺序不同,Set元素值可以是null,HashSet是Set接口的最常用的实现类。可以通过重写类的equals()和hashCode()方法定义对象相等的逻辑。
  • Iterator迭代器提供了遍历Collection集合元素的统一编程接口。
  • Map用于保存具有映射关系的数据。Map集合中保存着两组值,一组值用于保存Map里的key,另外一组值保存Map的value。key和value可以为null。
  • Map接口的put(K key,V value)用于向映射中添加一对key与value的映射关系,get(Object key)用于返回映射中key所对应的value。

Java面向对象笔记 • 【第7章 集合】的更多相关文章

  1. java 面向对象编程-- 第15章 集合框架

    1.  集合特点:元素类型不同.集合长度可变.空间不固定 2.  java中对一些数据结构和算法进行了封装即集合.集合也是一种对象,用于存储.检索.操作和传输对象. 3.  JCF(Java Coll ...

  2. Java面向对象程序设计第9章1-9

    Java面向对象程序设计第9章1-9 1. 线程和进程的联系和区别是什么? 联系: 一个进程可以包括多个线程. 区别: 进程: 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,它是系统 ...

  3. 20145330《Java学习笔记》第一章课后练习8知识总结以及IDEA初次尝试

    20145330<Java学习笔记>第一章课后练习8知识总结以及IDEA初次尝试 题目: 如果C:\workspace\Hello\src中有Main.java如下: package cc ...

  4. Java面向对象程序设计第14章3-8和第15章6

    Java面向对象程序设计第14章3-8和第15章6 3.完成下面方法中的代码,要求建立一个缓冲区,将字节输入流中的内容转为字符串. import java.io.*; public class tes ...

  5. Java面向对象程序设计第8章3-5

    Java面向对象程序设计第8章3-5 3.String类型有什么特点? 一旦赋值,便不能更改其指向的字符对象 如果更改,则会指向一个新的字符对象 不能为null 4.String什么时候进行值比较,什 ...

  6. Java面向对象程序设计第7章1-8

    Java面向对象程序设计第7章1-8 1."程序中凡是可能出现异常的地方必须进行捕获或拋出",这句话对吗? 不对. 异常分两类,runtime异常和非runtime异常. runt ...

  7. Java面向对象笔记 • 【第3章 继承与多态】

    全部章节   >>>> 本章目录 3.1 包 3.1.1 自定义包 3.1.2 包的导入 3.1.3 包的访问权限 3.1.4 实践练习 3.2 继承 3.2.1 继承概述 3 ...

  8. Java 学习笔记 ------第六章 继承与多态

    本章学习目标: 了解继承的目的 了解继承与多态的关系 知道如何重新定义方法 认识java.lang.object 简介垃圾回收机制 一.继承 继承是java面向对象编程技术的一块基石,因为它允许创建分 ...

  9. [Effective Java 读书笔记] 第8章 通用程序设计

    本章主要讲了以下几条基本的JAVA编程原则: 1.将局部变量的作用域控制在最小,在使用时才定义 2.for-each优于for循环 有三个例外(1,2点主旨就是,for each只能用于读取,不能用于 ...

随机推荐

  1. Echarts 实现tooltip自动显示自动播放

    1.其实这个很容易实现,一个 dispatchAction 方法就解决问题:但是博主在未实现该功能时是花了大力气,各种百度,各种搜: 很难找到简单粗暴的例子,大多数随便回一句你的问题就没下文: 废话太 ...

  2. 【力扣】122. 买卖股票的最佳时机 II

    给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格. 设计一个算法来计算你所能获取的最大利润.你可以尽可能地完成更多的交易(多次买卖一支股票). 注意:你不能同时参与多笔交易(你必须在再次 ...

  3. uni-app使用腾讯地图注意点

    地图map组件使用腾讯地图自定义样式: 1:在使用地图map组件腾讯地图时,获取本地定位,经纬度转地址与地址转经纬度解析时,小程序可以直接使用.但是h5版本会报跨域问题,目前前端没有找到更好的解决方法 ...

  4. C#中继承和多态

    1.继承的概念 继承是使用已存在的类的定义作为基础建立新类的技术,新类的定义可以增加新的数据或新的功能,也可以用已存在的类的功能. 为了提高软件模块的可复用性和可扩充性,以便提高软件的开发效率,我们总 ...

  5. Mysql配置 主主同步

    目录 一.准备 二.操作 A数据库操作 B数据库操作 A数据库操作 一.准备 1.两个数据库版本最好一致 2.两个数据库内数据保持一致,若不一致,可手动调整,比如A比B多一个库,那将这个库导入到B库, ...

  6. pipeline parameters指令

    目录 一.简介 二.类型 参数类型 多参数 一.简介 参数化pipeline是指通过传参来决定pipeline的行为.参数化让写pipeline就像写函数,而函数意味着可重用.更抽象.所以,通常使用参 ...

  7. 可恶的Math.random()

    生成随机数1-10   (包含1和10) 结果是这样的:Math.floor(Math.random()*10+1)  那么问题又来了 Math.floor(Math.random()*10)生成的只 ...

  8. JUC之Lock接口以及Synchronized回顾

    Lock接口 Synchronized关键字回顾: 多线程编程步骤(上): 创建资源类,在资源类创建属性和操作方法 创建多个线程,调用资源类的操作方法 创建线程的四种方式: 继承Thread 实现Ru ...

  9. 『忘了再学』Shell基础 — 2、Shell的作用与分类

    目录 1.Shell的作用 2.Shell的分类 1.Shell的作用 Shell除了能解释用户输入的命令,将它传递给内核,还可以: 调用其他程序,给其他程序传递数据或参数,并获取程序的处理结果. 在 ...

  10. CF508A Pasha and Pixels 题解

    Content 有一个 \(n\times m\) 的矩阵,一开始全部格子被染成白色. 接下来有 \(k\) 个操作,每一个操作表示把一个格子染成黑色.问第一次出现 \(2\times 2\) 的全部 ...