java的集合框架ListSetMap

news2024/11/27 7:05:59

什么是集合?

存储多个对象的单一对象(java容器)。

为什么不用数组?

集合与数组都是对数据进行存储操作的结构,简称java容器。
此时的存储主要是内存方面的,不涉及到持久话存储(.txt,.jpg,数据库)。
数组存储的缺点:
1、一但初始化,长度确定。
2、数组创建后,元素类型确定。
3、数组提供的方法有限。
4、数组不能够存储无序,不可重复的数据。

集合框架

集合框架有两个父接口:Collection和Map 和 Collections工具类。
集合框架体系

一、父接口Collection

单列集合,用来存储一个一个的对象。

向Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals方法。

方法简介
add(object obj)将元素obj添加到集合当中
size()获得添加元素的个数
addAll(Collection collection1)将集合collection1,添加到原有集合中
isEmpty()判断当前集合是否为空
clear()清空集合元素
boolean remove(object obj)通过元素的equals方法找到要删除的元素,并且只会删除找到的第一个元素
boolean removeAll(Collection coll)取当前集合的差集
boolean retainAll(Collection coll)把交集的结果存储到当前集合中,不影响coll
boolean equals(Object obj)判断集合元素是否相等
Object[] toArray()转成对象数组
hashcode()获取集合对象的哈希值
contains(Object obj)判断集合对象中是否包含obj,判断时会调用obj对象所在类的equals方法
containsAll(Collection coll)判断coll中元素是否都存在与当前集合中

集合—>数组

Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(789);
Object[] arr = coll.toArray();

数组—>集合

List<String> list = Arrays.asList(new String[] {"aa","bb","cc"});
//不能进行增删操作:因为转成的集合对象是Arrays里内部类的ArrayList,不是集合框架中的ArrayList。

//如果想要进行增删操作,需要新建一个集合对象。
List<String> list1 = new ArrayList<String>(list);

Collection集合对象遍历

Collection接口继承了java.lang.Iterable接口,该接口中有一个Iterator()方法。

迭代器Iterator

1、iterator只适用于遍历,它本身不具备承载对象的能力。如果需要创建迭代器对象,必须要先有一个被迭代的集合。

Collection coll = new ArrayList();
		coll.add(123);
		coll.add(234);
		coll.add("AA");
		Iterator it = coll.iterator();
		while(it.hasNext()) {
			Object obj = it.next();
			System.out.println(obj);

2、集合对象每次调用iterator都会得到一个全新的迭代器对象。默认的游标在集合第一个元素之前。
3、在迭代过程中,迭代器可以通过remove()方法删除集合中的元素,此remove并非是集合框架中的remove()方法。
4、如果在未调用next()方法之前或再之后调用两次remove(),调用remove方法,会报IllegalStateException

Collection coll = new ArrayList();
		coll.add(123);
		coll.add(234);
		coll.add("AA");
		Iterator it = coll.iterator();
		//hasNext():判断是否还有下一个元素
		while(it.hasNext()) {
			//next():1、指针下移 2、将下移后集合位置上的元素返回
			Object obj = it.next();
			if(obj.equals("AA")) {
				it.remove();
			}
		}
		Iterator it1 = coll.iterator();
		while(it1.hasNext()) {
			System.out.println(it1.next());
		}

foreach遍历

java5.0提供了foreach(增强for循环),可以对集合和数组进行遍历。
增强for循环底层仍然调用了iterator

for(遍历的元素类型 遍历元素的自定义名称:遍历结构名称){
	System.out.println(遍历元素的自定义名称);
}

常规for循环也可以实现集合的遍历

二、Collection的子接口1:List

List接口概述

1、鉴于java数组存储数据的局限性,通常使用List代替数组。
2、List集合中的元素有序,且可重复,集合中每个元素都有其对应的顺序索引–>常称为动态数组。
3、List的常用实现类有ArrayList,linkedList,Vector。_

ArrayList

List接口的主要实现类,线程不安全的,效率高。底层使用的是数组:Objec[] elementData存储。

LinkedList

对于频繁的删除,插入操作,LinkedList要比ArrayList效率要高,因为它的底层是双向链表存储,内部没有声明数组。线程也是不安全的。

Vector

作为List接口的古老实现类,它的线程是安全的,效率低。底层使用的是数组:Objec[] elementData存储。

List接口的常用方法

List除了继承了Collection方法外,List还添加了一些对于索引操作的方法。

方法简介
void add(int index,Object ele)在index处插入ele元素
boolean addAll(int index,Collection eles)在index处开始将eles集合中所有元素插入
Object get(int index)获取索引为index的元素
int indexof(Object obj)返回obj在集合中首次出现的位置,不存在返回-1
int lastIndexOf(Object obj)返回obj在集合中末次出现的位置,不存在返回-1
Object remove(int index)删除下标为index的集合元素,并返回此元素
Object set(int index,Object ele)设置index位置的元素为ele
List subList(int fromIndex,int toIndex)返回fromIndex到toIndex位置的子集合

List的遍历

1、迭代器Iterator

ArrayList list = new ArrayList();
		list.add(123);//自动装箱
		list.add(456);
		list.add("AA");
		Iterator it = list.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}

2、增强for循环

for(Object obj:list) {
			System.out.println(obj);
		}

3、普通for循环

for(int i=0;i<list.size();i++) {
			System.out.println(list.get(i));
		}

区分remove(int index)和remove(Object obj)

public static void main(String[] args) {
		ArrayList list = new ArrayList();
		list.add(1);//自动装箱
		list.add(2);
		list.add(3);
		updataList(list);
		System.out.println(list);
	}

	private static void updataList(ArrayList list) {
		list.remove(2);//这里的2指的是index
		list.remove(new Integer(2));//这里的2指的是对象
		
	}

三、Collection子接口2:Set

使用Set集合,必须重写元素所在类的hashcode()和equals()方法。

Set接口概述

1、Set接口是Collection的子接口,并没有提供额外的方法。
2、Set接口存储无序,且不可重复的数据。
3、Set接口判断数据是否重复不使用 “==”,而是equals方法。
4、Set的常用实现类:HashSet,LinkedHashSet,TreeSet。

HashSet

HashSet作为Set的主要实现类,线程不安全,可以存储NULL值。底层:数组+链表。

LinkedHashSet

做遍历操作时,可以按照添加的顺序遍历。

TreeSet

可以按照添加对象的指定属性进行排序。不能够添加所属不同类的对象。
底层采用红黑树结构,有序,查询速度比List快。

不可重复性与无序性描述

1、无序性!=随机性

所谓无序性是指,存储的数据在底层数组中并非按照索引顺序添加。而是根据数据的哈希值进行添加。

public static void main(String[] args) {
		Set set = new HashSet();
		set.add(123);
		set.add(456);
		set.add("AA");
		set.add("BB");
		System.out.println(set);
		
	}
以上代码第一次运行结果:[AA, BB, 456, 123]
           第二次运行:[AA, BB, 456, 123]

2、不可重复性

保证添加的元素按照equals判断时,不能返回true。即:相同的元素只能添加一个。

Set的存储过程

以HashSet为例:
		向HashSet集合添加元素a,首先调用a所在类的hashcode()方法,计算元素a的hash值。
		此哈希值接着通过某种算法计算出HashSet底层数组的存放位置(即,索引位置),判断
		数组此位置上是否有元素:
				如果此位置上没有其他元素,则a元素添加成功。
				如果此位置上其他元素b(或以链表形式存在多个元素),则比较元素a与元素b的哈希值:
						如果hash值不相同,添加成功。
						如果hash值相同,进而需要调用a所在类的equals()方法:
								equals()返回true,元素a添加失败。
								equals()返回false,元素添加成功。

在添加元素a时,若此位置上有其他元素b或多个元素,那么在这个索引位置的元素以链表结构存储:
	jdk7:元素a放到数组中,指向原来元素。如图1-2。
	jdk8:原来的元素在数组中,指向元素a。如图1-3。
	口诀:七上八下

存储流程图
在这里插入图片描述
图片1-2
图片1-2
图片1-3
1-3

LinkedHashSet无序性论证

在添加元素时,每个数据还维护了两个引用,记录此数据前一个数据位置和 后一个数据位置。实际存储的还是无序的。
对于频繁的遍历操作,LinkedHashSet效率高于HashSet。
在这里插入图片描述

TreeSet排序

自然排序(Comparable)

在自然排序中,比较两个对象是否相同的标准为:CompareTo()返回0,不再是equals()。

例子1:

public static void main(String[] args) {
		TreeSet set = new TreeSet();
		set.add(13);
		set.add(-56);
		set.add(5);
		set.add(56);
		System.out.println(set);
		
	}
结果为[-56, 5, 13, 56]    即,从小到大排序。

例子2:
按照姓名排序,元素所在类需要实现comparable接口,重写compareTo()方法。

TreeSet set = new TreeSet();
		set.add(new User("jack",14));
		set.add(new User("kite",14));
		set.add(new User("jom",14));
		set.add(new User("tonny",14));
		Iterator it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
结果:	User [name=jack, age=14]
		User [name=jom, age=14]
		User [name=kite, age=14]
		User [name=tonny, age=14]

元素所在类compareTo():

public int compareTo(Object o) {
		if(o instanceof User) {
			User user = (User)o;
			return this.name.compareTo(user.name);
		}else {
			throw new RuntimeException("输入类型不匹配");
		}
		
	}

定制排序(Comparator)

需要创建comparator对象。
在自然排序中,比较两个对象是否相同的标准为:Compare()返回0,不再是equals()。

public static void main(String[] args) {
		Comparator com = new Comparator() {
			//年龄从小到大排列
			@Override
			public int compare(Object o1, Object o2) {
				if(o1 instanceof User && o2 instanceof User) {
					User u1 = (User)o1;
					User u2 = (User)o2;
					return Integer.compare(u1.getAge(), u2.getAge());
				}else{
					throw new RuntimeException("输入数据类型不匹配");
				}
			}
		};
		TreeSet set = new TreeSet(com);//不加com,按照自然排序
		set.add(new User("jack",14));
		set.add(new User("kite",52));
		set.add(new User("jom",19));
		set.add(new User("tonny",1));
		Iterator it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}

四、Map接口

双列数据,存储key-value对数据。存储无序的双列数据。
key所在的类,需要重写hashcode()和equals()方法。
value所在的类,需要重写equals()方法。

Map实现类的对比

HashMap:作为map的主要实现类;线程不安全,效率高,存储null的key和value,底层:数组+链表(jdk7及之前),数组+链表+红黑树(jdk8)。

LinkedHashMap:在遍历map元素时,可以按照添加顺序进行遍历。

原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个元素和后一个元素。
	  对于频繁的遍历操作,效率高于HashMap。

TreeMap:按照添加的key-value对进行排序(按照key排序),实现排序遍历,考虑key的定制排序或自然排序。底层是红黑树。
HashTable:作为古老的实现类,线程安全,效率低,不能存储null的key和value。
Properties:HashTable的子类,常用来处理配置文件,key和value都是String类型。

Map结构

key:无序的,不可重复的,使用Set存储所有key。
value:无序的,可重复的,使用Collection存储所有value。
一个键值对:key-value构成了一个Entry对象,Entry:无序的,不可重复,使用Set存储。

Map接口的常用方法

增删改简介
Object put(Object key,Object value)将指定key-value添加/修改 当前mao对象中
void putAll(Map m)将m中的key-value对存放到当前map中
Object remove(Object key)移除指定key的key-value对,并返回value
void clear()清空当前map中的所有数据
查询简介
Object get(Object key)获取指定key对应的value
boolean containsKey(Object key)是否包含指定的key
boolean containsValue(Object value)是否包含指定的value
int size()返回map中key-value对的个数
boolean isEmpty()判断当前map是否为空
boolean equals(Object obj)判断当前map和参数对象obj是否相等
元视图操作简介
Set keySet()返回所有key构成的Set集合
Collection values()返回所有value构成的Collection集合
Set entrySet()返回所有key-value对构成的Set集合

HashMap的底层实现原理

jdk7:

HashMap map = new HashMap();
在实例化后,底层创建了一个长度为16的一维数组Entry[] table.
....
map.put(key,value);
....
首先,调用key所在类的hashcode()计算key的hash值,此hash值通过某种算法计算以后,得到在Entry数组中存放的位置。
如果此位置上的数据为空,此时的key-value添加成功。
如果此位置上的数据不为空,(意味着此位置上存在一个或者多个数据(以链表形式存在)),比较key和已经存在的一个或多个数据的hash值:
		如果key的hash值与已经存在数据的hash值都不相同,此时key-value添加成功。
		如果key的hash值与已经存在某个数据的hash值相同,调用key所在类的equals():
				如果equals()返回false:此时key-value添加成功。
				如果equals()返回true:将value替换原来的数据。
在不断添加的过程中,会涉及到扩容问题,默认的扩容方式为:扩容为原来容量的2倍,并将原来的数据复制过来。

jdk8相较于jdk7在底层实现方面的不同:
1、new HashMap():底层没有创建一个长度为16的数组。
2、jdk8底层数组是:Node[],而非Entry[]。
3、首次调用put()方法时,底层创建长度为16的数组。
4、
jdk7底层结构只 有:数组+链表。jdk8底层结构:数组+链表+红黑树。
当数组的某一个索引位置上的元素以链表形式存在的数据个数 >8 且当前数组长度 >64 时,此时此索引位置上的所有数据改为使用红黑树存储。

HashMap遍历

	public static void main(String[] args) {
			HashMap map = new HashMap();
			map.put("a", 15);
			map.put(12, 32);
			map.put("s", "aa");
			map.put("S", "kk");
			//遍历所有key集:keySet()
			Set set = map.keySet();
			Iterator it = set.iterator();
			while(it.hasNext()) {
				System.out.println(it.next());
			}
			//遍历所有value集:values()
			Collection values = map.values();
			for(Object obj:values) {
				System.out.println(obj);
			}
			//遍历所有key-value(Entry)
			Set EntrySet = map.entrySet();
			Iterator it1 = EntrySet.iterator();
			while(it1.hasNext()) {
				Object obj = it1.next();
				//entrySet集合中的元素都是entry
				Map.Entry entry = (Map.Entry) obj;//Map.Entry是Map的内部接口
				System.out.println(entry.getKey()+","+entry.getValue());
			}
	}

TreeMap排序

向TreeMap中添加的key-value,要求key必须有同一个类创建。
用key进行排序,自然排序与定制排序。详见TreeSet。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/724130.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

XXX汽车SAP ERP系统预月结模式助力成本高效结算(投稿数字化月报二)

XXX汽车业务复杂&#xff0c;零部件数据繁多&#xff0c;SAP ERP系统实施时&#xff0c;引进了行业的领先模式&#xff0c;所以系统挑战相对大&#xff0c;尤其是在月底进行账务结算时&#xff0c;出现过结算异常的情况&#xff0c;而公司对月结有固定的完成时间&#xff0c;因…

Seafile搭建个人云盘 - 内网穿透实现在外随时随地访问

文章目录 1. 前言2. SeaFile云盘设置2.1 Owncould的安装环境设置2.2 SeaFile下载安装2.3 SeaFile的配置 3. cpolar内网穿透3.1 Cpolar下载安装3.2 Cpolar的注册3.3 Cpolar云端设置3.4 Cpolar本地设置 4. 公网访问测试5. 结语 转载自cpolar极点云文章&#xff1a;使用SeaFile搭建…

Java 设计模式——代理模式

目录 1.概述2.结构3.静态代理3.1.实现3.2.优缺点 4.动态代理4.1.JDK 动态代理4.1.1.实现4.1.2.思考4.1.2.1.ProxyFactory 是代理类吗&#xff1f;4.1.2.2.动态代理的执行流程是什么样&#xff1f;4.1.2.3.为什么 JDK 动态代理只能代理有接口的类&#xff1f; 4.2.CGLIB 动态代理…

初识mysql数据库之数据类型

目录 一、数据类型 1. 数据类型分类 2. 数值类型 2.1 整数类型 2.2 位字段类型 2.3 小数类型 3. 字符串类型 3.1 char 3.2 varchar 4. 日期和时间类型 5. enum和set 5.1 enum介绍 5.2 set介绍 5.3 enum测试 5.4 set测试 5.5 enum的查找 5.6 set的查找 一、数据…

DAY40:贪心算法(九)单调递增的数字(贪心的思路)

文章目录 738.单调递增的数字&#xff08;暴力解也需要看一下&#xff09;暴力解写法注意&#xff1a;必须引入isIncreasing变量的原因 贪心思路遍历顺序 最开始的写法debug测试&#xff1a;逻辑错误 修改版debug测试int转化为字符串的原因to_string和stoi的用法 总结 738.单调…

CPCI-QU-216A正交解码计数器卡

CPCI-QU-216A是用于高速正交解码计数器CPCI板卡&#xff0c;包括6个立计数器&#xff0c;支持索引锁存&#xff0c;支持步长比较输出&#xff0c; 6个高速隔离输入&#xff0c;6个高速隔离输出。 l 32位 cPCI接口 l 6通道隔离输入 l 6通道隔离输出&#xff08;默认用于比较值输…

0125 计算机系统概述

目录 1.计算机系统概述 1.1计算机发展历程 1.2计算机系统层次结构 计算机硬件 计算机软件 计算机系统层次结构 计算机系统工作原理 指令执行过程 1.2部分习题 1.3计算机性能指标 计算机主要性能指标 几个专业术语 1.3部分习题 1.计算机系统概述 1.1计算机发展历程…

三星面板产能紧缺?超半数三星电视机采用其他厂商的面板

今年有超过50%的三星电视未使用自家屏幕&#xff0c;而是采用了来自中国厂商的大部分零件。 据韩国媒体《The Elec》报道&#xff0c;超过一半的三星电视机使用了其他厂商的面板。根据三星电子面板库存明细&#xff0c;大部分的面板来自中国的华星光电、惠科、京东方和咸阳彩虹…

小红书数据分析!Citywalk声量大涨,年轻人为何迷恋它?

近来&#xff0c;一种新型旅游形式——citywalk火了。惬意的城市漫游&#xff0c;成为时下年轻人最潮的逛GAI方式。小红书上更是掀起了citywalk游记潮流&#xff0c;人们纷纷在平台分享记录自己的出游感受。citywalk具体怎么玩&#xff1f;哪些人爱玩&#xff1f;通过分析小红书…

我们来谈谈tcp

"让新离开地表&#xff0c;才能找到盘旋爬升的动力。" 一、认识Tcp报头 (1) 协议报头格式 我们先来认识认识tcp协议报头字段。 跟tcp协议字段报头比起来&#xff0c;udp可真是太轻松了。 协议字段作用源/目的端口号从哪里来&#xff0c;到哪里去32位序号/32位确认…

前端vue入门(纯代码)21_vuex

努力不一定成功&#xff0c;但是&#xff0c;不努力一定很轻松&#xff01;&#xff01;&#xff01; 【23.Vuex】 [可以去官网看看Vuex3文档](Vuex 是什么&#xff1f; | Vuex (vuejs.org)) 问题1&#xff1a;Vuex是什么&#xff1f; 【官方理解1】&#xff1a;Vuex 是一个专…

vue中的.env全局配置

关于文件名&#xff1a; .env 全局默认配置文件&#xff0c;不论什么环境都会加载合并 .env.development 开发环境下的配置文件 .env.production 生产环境下的配置文件 .env文件配置&#xff1a; 我这里要讲的env配置是用启动命令启动项目来配置不同的全局变量 我配置了两…

十七、Jenkins(centos7系统)运行python3代码

十七、Jenkins(centos7系统)运行python3代码 source /usr/python/envs/everyday/bin/activate #激活python3 虚拟环境 创建虚拟环境&#xff1a;https://blog.csdn.net/qq_42846555/article/details/131579627 source /usr/python/envs/everyday/bin/activate #激活python3 虚…

自我介绍,千万别来虚的!

大家好&#xff0c;我是鲏。 已经帮小伙伴改了 500 多份简历了&#xff0c;也发现了一些大家写简历时的共性问题。其中让我印象比较深刻的一个点就是 自我介绍 &#xff0c;基本上所有同学的自我介绍都是这么写的&#xff1a; 读这篇文章的朋友们&#xff0c;你是不是也是这么…

困于“耐用焦虑”的绿源,还在歧路徘徊?

老牌两轮电动车品牌绿源上市之旅“多歧路”。 日前&#xff0c;北京市市场监督管理局公布北京市电动自行车产品质量监督抽查结果&#xff0c;绿源两款电动自行车因存在问题被点名&#xff0c;充电器和蓄电池、整车质量、控制系统等不符合标准。 而在此前&#xff0c;绿源还向港…

秒懂算法 | 围棋中的Alpha-Beta剪枝算法

01、Alpha-Beta剪枝算法 极小化极大算法会遍历所有的可能性&#xff0c;但是根据经验可以知道&#xff0c;并不是所有的选项都需要进行深入的考虑&#xff0c;存在着某些明显不利的选项&#xff0c;当出现这种选项时就可以换一种思路进行考虑了。Alpha-Beta剪枝算法的出现正是…

网络投票平台发起投票平台投票吧网络投票平台

小程序投票活动如何做&#xff1f;很多企业在运营当中&#xff0c;都会通过投票活动来进行推广&#xff0c;从而达到吸粉、增加用户粘度等效果。而此类投票活动&#xff0c;通过小程序就可以实现&#xff0c;操作简单。 我们现在要以“青春大不同”为主题进行一次投票活动&…

系统架构设计师-软件工程(3)

一、软件系统建模 1、结构化建模方法 结构化建模方法是以过程为中心的技术&#xff0c;可用于分析一个现有系统以及定义新系统的业务需求。结构化建模方法所绘制的模型称为数据流图&#xff08;DFD&#xff09;。对于流程较为稳定的系统可考虑结构化建模方法。 2、信息工程建模…

linux中的目录文件都是用来做什么的

1、linux目录系列 - /bin、/sbin目录 我们平时使用的一些命令&#xff0c;是以2进制的格式存放在bin目录下面。例如:cat、chmod、chown、cp、date、find、gzip、kill、ln、ls、mount、mv、ping、pwd、rm、su、tar、vi等。/sbin下存放的是超级用户权限的系统指令。主要放置一些系…

Python采集双色球历史开奖信息,看看哪个号中奖概率更大

目录标题 前言知识点:开发环境:基本流程:代码展示尾语 前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 知识点: 爬虫基本流程 requests的使用 动态数据抓包 开发环境: 解释器: python 3.8 编辑器: pycharm 2022.3 requests >>> pip install requests 第三…