Java面向对象笔记 • 【第7章 集合】
全部章节 >>>>
本章目录
7.1 集合概述7
7.1.1 Java集合体系概述
为了使程序方便地存储和操纵数目不固定的一组数据,JDK类库中提供了Java集合,所有Java集合类都位于java.util包中。与Java数组不同,Java集合不能存放基本数据类型,而只能存放对象。
Java集合类主要由两个接口派生而出,即Collection和Map接口。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上 | 
| boolean addAll(int index, Collection collection) | 在index位置后添加容器collection中所有的元素 | 
| Object get(int index) | 取出下标为index的位置的元素 | 
| int indexOf(Object element) | 查找对象element在List中第一次出现的位置 | 
| int lastIndexOf(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章 集合】的更多相关文章
- java 面向对象编程-- 第15章 集合框架
		1. 集合特点:元素类型不同.集合长度可变.空间不固定 2. java中对一些数据结构和算法进行了封装即集合.集合也是一种对象,用于存储.检索.操作和传输对象. 3. JCF(Java Coll ... 
- Java面向对象程序设计第9章1-9
		Java面向对象程序设计第9章1-9 1. 线程和进程的联系和区别是什么? 联系: 一个进程可以包括多个线程. 区别: 进程: 进程是一个具有一定独立功能的程序关于某个数据集合的一次运行活动,它是系统 ... 
- 20145330《Java学习笔记》第一章课后练习8知识总结以及IDEA初次尝试
		20145330<Java学习笔记>第一章课后练习8知识总结以及IDEA初次尝试 题目: 如果C:\workspace\Hello\src中有Main.java如下: package cc ... 
- Java面向对象程序设计第14章3-8和第15章6
		Java面向对象程序设计第14章3-8和第15章6 3.完成下面方法中的代码,要求建立一个缓冲区,将字节输入流中的内容转为字符串. import java.io.*; public class tes ... 
- Java面向对象程序设计第8章3-5
		Java面向对象程序设计第8章3-5 3.String类型有什么特点? 一旦赋值,便不能更改其指向的字符对象 如果更改,则会指向一个新的字符对象 不能为null 4.String什么时候进行值比较,什 ... 
- Java面向对象程序设计第7章1-8
		Java面向对象程序设计第7章1-8 1."程序中凡是可能出现异常的地方必须进行捕获或拋出",这句话对吗? 不对. 异常分两类,runtime异常和非runtime异常. runt ... 
- Java面向对象笔记 • 【第3章 继承与多态】
		全部章节 >>>> 本章目录 3.1 包 3.1.1 自定义包 3.1.2 包的导入 3.1.3 包的访问权限 3.1.4 实践练习 3.2 继承 3.2.1 继承概述 3 ... 
- Java 学习笔记 ------第六章 继承与多态
		本章学习目标: 了解继承的目的 了解继承与多态的关系 知道如何重新定义方法 认识java.lang.object 简介垃圾回收机制 一.继承 继承是java面向对象编程技术的一块基石,因为它允许创建分 ... 
- [Effective Java 读书笔记] 第8章 通用程序设计
		本章主要讲了以下几条基本的JAVA编程原则: 1.将局部变量的作用域控制在最小,在使用时才定义 2.for-each优于for循环 有三个例外(1,2点主旨就是,for each只能用于读取,不能用于 ... 
随机推荐
- 双向循环链表模板类(C++)
			双向链表又称为双链表,使用双向链表的目的是为了解决在链表中访问直接前驱和后继的问题.其设置前驱后继指针的目的,就是为了节省其时间开销,也就是用空间换时间. 在双向链表的每个节点中应有两个链接指针作为它 ... 
- Copy constructor vs assignment operator in C++
			Difficulty Level: Rookie Consider the following C++ program. 1 #include<iostream> 2 #include&l ... 
- Java 使用slf4j记录日志
			引入依赖 <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12< ... 
- sql优化的8种方式 (下)
			五.条件列表值如果连续使用between替代in 六.无重复记录的结果集使用union all合并 MySQL数据库中使用union或union all运算符将一个或多个列数相同的查询结 ... 
- spring cloud config center Git SSH configuration
			Git SSH configuration using properties By default, the JGit library used by Spring Cloud Config Serv ... 
- sftp 上传下载 命令介绍
			sftp是Secure FileTransferProtocol的缩写,安全文件传送协议.可以为传输文件提供一种安全的加密方法. sftp与 ftp有着几乎一样的语法和功能.SFTP为 SSH的一部分 ... 
- solr8.2
			https://www.cnblogs.com/carlosouyang/p/11352779.html 
- Jenkins pipeline声明式语法
			目录 一.最简结构 二.简单例子 一.最简结构 pipeline { agent any stages { stage('pull') { st ... 
- 【分布式技术专题】「OSS中间件系列」Minio的文件服务的存储模型及整合Java客户端访问的实战指南
			Minio的元数据 数据存储 MinIO对象存储系统没有元数据数据库,所有的操作都是对象级别的粒度的,这种做法的优势是: 个别对象的失效,不会溢出为更大级别的系统失效. 便于实现"强一致性& ... 
- [BUUCTF]REVERSE——rsa
			rsa 附件 题目是rsa,首先了解一下什么是rsa加密,具体的看这个文章 首先大概介绍下RSA加密解密 RSA加密是对明文的E次方后除以N后求余数的过程 公钥n = p * q,其中p和q是两个大素 ... 
 
			
		

