java 类 解析_Java集合类解析 ***

collection集合

58c754484332d008356fec751d487d55.png

Map集合

fd244b99e30b4994c42eac78b4535ae0.png

Hashtable和HashMap的区别:

Hashtable的方法是同步的,而HashMap的方法不是。

HashMap可以将空值作为一个表的条目的key或value。

Collection接口

Collection接口是List、Set和Queue接口的父接口,该接口里定义的方法既可用于操作Set集合,也可用于操作List和Queue集Collection提供了大量添加、删除、访问的方法来访问集合元素。主要的方法如下:

1b7f29e01873bbcffe58d29b2644f75d.png

Java中的集合类包含的内容很多而且很重要,很多数据的存储和处理(排序,去重,筛选等)都需要通过集合类来完成。

首先java中集合类主要有两大分支:

(1)Collection (2)Map

先看它们的类图:

(1)Collection

627600efc5eabe3f8775fd459f844b1b.png

(2)Map

ed3e45c10be5d81ff4bde976bab9497d.png

可以看到它们之间的关系纷繁复杂,如果不系统的学习一下,还真是不知道有什么区别,该怎么选择。由于HashSet的内部实现原理是使用了HashMap,所以我们的学习路线为先学习Map集合类,然后再来学习Collection集合类。

(1)HashMap和Hashtable ( 注意table是小写的t,搞不懂为什么要这样,老是会写错。。。)

首先来看HashMap和HashTable,这两兄弟经常被放到一起来比较,那么它们有什么不一样呢?

a.HashMap不是线程安全的;HashTable是线程安全的,其线程安全是通过Sychronize实现。

b.由于上述原因,HashMap效率高于HashTable。

c.HashMap的键可以为null,HashTable不可以。

d.多线程环境下,通常也不是用HashTable,因为效率低。HashMap配合Collections工具类使用实现线程安全。同时还有ConcurrentHashMap可以选择,该类的线程安全是通过Lock的方式实现的,所以效率高于Hashtable。

好,比较了他们的不一样后,来讲讲它们的原理。

数组,链表,哈希表。各有优劣,顺便提一下,数组连续内存空间,查找速度快,增删慢;链表充分利用了内存,存储空间是不连续的,首尾存储上下一个节点的信息,所以寻址麻烦,查找速度慢,但是增删快;哈希表呢,综合了它们两个的有点,一个哈希表,由数组和链表组成。假设一条链表有1000个节点,现在查找最后一个节点,就得从第一个遍历到最后一个;如果用哈希表,将这条链表分为10组,用一个容量为10数组来存储这10组链表的头结点(a[0] = 0 , a[1] = 100 , a[2] = 200 …)。这样寻址就快了。

HashMap实现原理就是上述原理了,当然其具体实现还有很多其他的东西。Hashtable同理,只不过做了同步处理。

Hash碰撞,不同的key根据hash算法算出的值可能一样,如果一样就是所谓的碰撞。

优化措施:

(1) HashMap的扩容代价非常大,要生成一个新的桶数组,然后要把所有元素都重新Hash落桶一次,几乎等于重新执行了一次所有元素的put。所以如果我们对Map的大小有一个范围的话,可以在构造时给定大小,一般大小设置为:(int) ((float) expectedSize / 0.75F + 1.0F)。

(2) key的设计尽量简洁。

HashMap一些功能实现:

a.按值排序

HashMap按值排序通过Collections的sort方法,在实现排序之前,我们先看看HashMap的几种遍历方式:

//Collection And Map

public static void testCM(){

//Collection

Map hs = new HashMap();

int i = 0;

hs.put(199, "序号:"+201);

while(i<50){

hs.put(i, "序号:"+i);

i++;

}

hs.put(-1, "序号:"+200);

hs.put(200, "序号:"+200);

//遍历方式一:for each遍历HashMap的entryset,注意这种方式在定义的时候就必须写成

//Map hs,不能写成Map hs;

for(Entry entry : hs.entrySet()){

System.out.println("key:"+entry.getKey()+" value:"+entry.getValue());

}

//遍历方式二:使用EntrySet的Iterator

Iterator> iterator = hs.entrySet().iterator();

while(iterator.hasNext()){

Entry entry = iterator.next();

System.out.println("key:"+entry.getKey()+" value:"+entry.getValue());

};

//遍历方式三:for each直接使用HashMap的keyset

for(Integer key : hs.keySet()){

System.out.println("key:"+key+" value:"+hs.get(key));

};

//遍历方式四:使用keyset的Iterator

Iterator keyIterator = hs.keySet().iterator();

while(keyIterator.hasNext()){

Integer key = (Integer)keyIterator.next();

System.out.println("key:"+key+" value:"+hs.get(key));

}

}

(1)使用keyset的两种方式都会遍历两次,所以效率没有使用EntrySet高。

(2)HashMap输出是无序的,这个无序不是说每次遍历的结果顺序不一样,而是说与插入顺序不一样。

接下来我们看按值排序,注释比较详细就不赘述过程了。

//对HashMap排序

public static void sortHashMap(Map hashmap){

System.out.println("排序后");

//第一步,用HashMap构造一个LinkedList

Set> sets = hashmap.entrySet();

LinkedList> linkedList = new LinkedList>(sets);

//用Collections的sort方法排序

Collections.sort(linkedList , new Comparator>(){

@Override

public int compare(Entry o1, Entry o2) {

// TODO Auto-generated method stub

/*String object1 = (String) o1.getValue();

String object2 = (String) o2.getValue();

return object1.compareTo(object2);*/

return o1.getValue().compareTo(o2.getValue());

}

});

//第三步,将排序后的list赋值给LinkedHashMap

Map map = new LinkedHashMap();

for(Entry entry : linkedList){

map.put(entry.getKey(), entry.getValue());

}

for(Entry entry : map.entrySet()){

System.out.println("key:"+entry.getKey()+" value:"+entry.getValue());

}

}

b.按键排序

HashMap按键排序要比按值排序方法容易实现,而且方法很多,下面一一介绍。

第一种:还是熟悉的配方还是熟悉的味道,用Collections的sort方法,只是更改一下比较规则。

第二种:TreeMap是按键排序的,默认升序,所以可以通过TreeMap来实现。

public static void sortHashMapByKey(Map hashmap){

System.out.println("按键排序后");

//第一步:先创建一个TreeMap实例,构造函数传入一个Comparator对象。

TreeMap treemap = new TreeMap(new Comparator(){

@Override

public int compare(Integer o1,Integer o2) {

// TODO Auto-generated method stub

return Integer.compare(o1, o2);

}

});

//第二步:将要排序的HashMap添加到我们构造的TreeMap中。

treemap.putAll(hashmap);

for(Entry entry : treemap.entrySet()){

System.out.println("key:"+entry.getKey()+" value:"+entry.getValue());

}

}

第三种:可以通过keyset取出所有的key,然后将key排序,再有序的将key-value键值对存到LinkedHashMap中,这个就不贴代码了,有兴趣的可以自己去尝试一下。

c.value去重

对于HashMap而言,它的key是不能重复的,但是它的value是可以重复的,有的时候我们要将重复的部分剔除掉。

方法一:将HashMap的key-value对调,然后赋值给一个新的HashMap,由于key的不可重复性,此时就将重复值去掉了。最后将新得到的HashMap的key-value再对调一次即可。

d.HashMap线程同步

第一种:

Map hs = new HashMap();

hs = Collections.synchronizedMap(hs);

第二种:

ConcurrentHashMap hs = new ConcurrentHashMap();

(2)IdentifyHashMap

IdentityHashMap与HashMap基本相似,只是当两个key严格相等时,即key1==key2时,它才认为两个key是相等的 。IdentityHashMap也允许使用null,但不保证键值对之间的顺序。

(3)WeakHashMap

WeakHashMap与HashMap的用法基本相同,区别在于:后者的key保留对象的强引用,即只要HashMap对象不被销毁,其对象所有key所引用的对象不会被垃圾回收,HashMap也不会自动删除这些key所对应的键值对对象。但WeakHashMap的key所引用的对象没有被其他强引用变量所引用,则这些key所引用的对象可能被回收。WeakHashMap中的每个key对象保存了实际对象的弱引用,当回收了该key所对应的实际对象后,WeakHashMap会自动删除该key所对应的键值对。

接下来是Collection接口及其子类:

(4)ArrayList , LinkedList , Vector

(1)首先,说说它们的关系和区别。ArrayList和Vector本质都是用数组实现的,而LinkList是用双链表实现的;所以,Arraylist和Vector在查找效率上比较高,增删效率比较低;LinkedList则正好相反。ArrayList是线程不安全的,Vector是线程安全的,效率肯定没有ArrayList高了。实际中一般也不怎么用Vector,可以自己做线程同步,也可以用Collections配合ArrayList实现线程同步。

(2)Tips

前面多次提到扩容的代价很高,所以如果能确定容量的大致范围就可以在创建实例的时候指定,注意,这个仅限于ArrayList和Vector哟:

ArrayList arrayList = new ArrayList(100);

arrayList.ensureCapacity(200);

Vector vector = new Vector(100);

vector.ensureCapacity(200);

(3)其他功能实现

a.排序

List的排序的话就是使用Collections的sort方法,构造Comparator或者让List中的对象实现Comparaable都可以,这里就不贴代码了。

b.去重

第一种:用Iterator遍历,遍历出来的放到一个临时List中,放之前用contains判断一下。

第二种:利用set的不可重复性,只需三步走。

//第一步:用HashSet的特性去重

HashSet tempSet = new HashSet(arrayList);

//第二步:将arrayList清除

tempSet.clear();

//第三步:将去重后的重新赋给List

arrayList.addAll(tempSet);

(5)Stack

Stack呢,是继承自Vector的,所以用法啊,线程安全什么的跟Vector都差不多,只是有几个地方需要注意:

第一:add()和push(),stack是将最后一个element作为栈顶的,所以这两个方法对stack而言是没什么区别的,但是,它们的返回值不一样,add()返回boolean,就是添加成功了没有;push()返回的是你添加的元素。为了可读性以及将它跟栈有一丢丢联系,推荐使用push。

第二:peek()和pop(),这两个方法都能得到栈顶元素,区别是peek()只是读取,对原栈没有什么影响;pop(),从字面上就能理解,出栈,所以原栈的栈顶元素就没了。

(6)HashSet和TreeSet

Set集合类的特点就是可以去重,它们的内部实现都是基于Map的,用的是Map的key,所以知道为什么可以去重复了吧。 既然要去重,那么久需要比较,既然要比较,那么久需要了解怎么比较的,不然它将1等于2了,你怎么办?

比较是基于hascode()方法和equals()方法的,所以必要情况下需要重新这两个方法。

好了,到了总结的时候了,其实你会发现集合类虽然看起来多,但是都是很有规律的。ArrayList,LinkedList一个无序,一个有序;HashSet,TreeSet一个无序,一个有序;HashMap,LinkedHasmMap,一个无序,一个有序;Vector和HashTable,Stack是线程安全的,但是效率低;线程不安全的类都可以配合Collections得到线程安全的类。

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

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

相关文章

JVM的生命周期

1.加载&#xff08;Loading&#xff09;&#xff1a; 在加载阶段&#xff0c;JVM会找到并加载Java字节码文件。加载阶段分为三个步骤&#xff1a;通过类的全限定名找到对应的字节码文件&#xff0c;创建一个与该类相关的Class对象&#xff0c;将类的静态数据结构存储在方法区中…

lvds接口屏线安装图解_五分钟让你学会液晶拼接屏安装方法

液晶拼接屏成为目前比较热门的大屏显示系统&#xff0c;技术比较成熟&#xff0c;清晰度高、维护方便&#xff0c;性价比也还不错&#xff0c;市场需求量较大。但是液晶拼接屏安装方法很多人并不了解&#xff0c;下面小编就来简单介绍一下。以46寸液晶拼接屏指导安装为例&#…

cmd255command.executereader()打印连接错误_打印经常遇到的几个问题,轻松解决

在平常的工作中&#xff0c;我们经常会遇到一些打印问题&#xff0c;今天就分享下几个常见的故障问题解决。wps/office文档一点击打印就卡死这种一般默认打印机设置的是其它电脑共享的情况下出现的&#xff0c;当与主机的连接出现异常或者主机的打印设置有问题时&#xff0c;就…

如何制定客户留存策略_商客通:办理石家庄400电话如何留存客户

【办理石家庄400电话如何留存客户】在如今理性消费的市场&#xff0c;400电话能够为在消费者心中为企业营造一份信任感&#xff0c;彰显企业关怀及企业责任感&#xff1b;为消费者提供畅达的通信渠道、完善的企业服务保障。石家庄400电话搬家不换号石家庄企业在公司搬迁或者员工…

普中51控制火焰传感器_汽车爆震传感器的工作原理及的检测方法、处理

汽车爆震传感器的工作原理及的检测方法、处理黄永刚1 爆震传感器的工作原理按照结构的不同&#xff0c;可以将汽车爆震传感器分为压电式非共振型爆震传感器、压电式共振型爆震传感器和压电式火花塞座金属垫型爆震传感器&#xff0c;又可以分为压电式爆震传感器和电感式爆震传感…

java绘制流程图_如何才能更好地绘制计算机毕业设计中各种图表

“ 毕设论文中的各种图表是不可或缺的&#xff0c;如果只是单纯的文字&#xff0c;或者图表较少&#xff0c;达不到要求的话&#xff0c;最终是通过不了答辩审核的&#xff01;”目前绘制图表的软件很多&#xff0c;比如VISIO等&#xff0c;切记尽量不要使用word软件进行绘制&a…

arcgis加载dwg显示一个点_Arcgis添加控制点配准校正影像,更新校正之后,其他软件打开之后,影像位置没有校正解决办法...

使用有偏移的两景影像srcImg.tif 和 refImg.tif举例&#xff0c;用refImg.tif为参考&#xff0c;把待校正影像srcImg.tif&#xff0c;与refImg.tif配准一致。原始影像如下所示&#xff1a;这里就不演示如何采集控制点了&#xff0c;大家可以搜索arcgis配准详细步骤&#xff1b;…

空投坐标怎么看6_嗦粉不咯?桂林米粉店将分三四五星级,你怎么看? 旅行 6 月 4 日热点速递...

吃货们请听好&#xff0c;以下内容可能与你有关~来看今日好问广西无疑是嗦粉星人的圣地&#xff0c;桂林米粉、柳州螺蛳粉、南宁老友粉 ...... 用手指都不够数。这不&#xff0c;桂林发布「米粉新政」&#xff0c;从 7 月起桂林米粉店划分为三星级、四星级、五星级三个等级。如…

java list应用_java中list集合的应用

java中list集合的应用 1.数组列数据的添加与删除&#xff1a; List list new LinkedList(); list new ArrayList(); 产生一个数组列对象并建立双向连表。 连表分为单向连表和双向连表&#xff1b;单向连表就像&#xff1a;a 只能到 b&#xff0c;b 不能到 c&#xff1b;双向连…

ubuntu 自动加载ko_开屏广告太烦人?用这个只有 2M 的 App,助你自动跳过 5 秒等待...

手机上的什么按钮会让你不假思索点击&#xff1f;除了抢红包&#xff0c;恐怕就是应用启动页的「跳过广告」了。「跳过广告」会这么容易被叉掉吗&#xff1f;显然&#xff0c;如果不够快准狠&#xff0c;连戳几次没反应不说&#xff0c;还有可能在戳偏后继续忍受广告跳转……掐…

怎样查看cudnn版本_tensorflowGPU版本踩坑记录

终于安装完成了tensorflow&#xff0c;写一下过程开心的记录一下之前按照网上的教程&#xff0c;装了半天&#xff0c;下对应的cuda和cudnn&#xff0c;搞了半天&#xff0c;结果is_gpu_avaliable()函数通不过&#xff0c;查了半天&#xff0c;只找到cuda和cudnn版本不对应&…

java继承调用先后_「继承顺序」JAVA继承顺序 - seo实验室

继承顺序当使用继承这个特性时&#xff0c;程序是如何执行的&#xff1b;继承的初始化顺序1.初始化父类再初始子类2.先执行初始化对象中属性&#xff0c;再执行构造方法中的初始化当使用继承这个特性时&#xff0c;程序是如何执行的呢&#xff0c;也就是说我们需要关注继承的初…

手机连接蓝牙扫码枪_宝马车与手机无法蓝牙连接的技术通报

点击↑上方蓝字关注置顶&#xff0c;懂车&#xff0c;更懂宝马&#xff01;故障现象&#xff1a;手机电话与车辆无法连接&#xff0c;故障信息显示“设备无法连接”&#xff0c;诊断时输出故障代码&#xff1a;B7F8BB - “无法启动蓝牙”。涉及车型&#xff1a;F40G02 G05 G06 …

gdb tui 安装_GDB 单步调试汇编

之前在看汇编的时候一直是肉眼看GCC -S的结果&#xff0c;缺点是很不直观&#xff0c;无法实时的看到寄存器的值&#xff0c;所以研究了下如何用GDB调试汇编。当然&#xff0c;写这篇文章更重要的一个目的是半年没有写博客了&#xff0c;博客要长草了。^_^调试汇编的需求有几点…

java中的异常处理语句_Java中实现异常处理的基础知识

Java中实现异常处理的基础知识异常 (Exception)&#xff1a;发生于程序执行期间&#xff0c;表明出现了一个非法的运行状况。许多JDK中的方法在检测到非法情况时&#xff0c;都会抛出一个异常对象。例如&#xff1a;数组越界和被0除。源代码示例&#xff1a;packageyanzheng;//…

改变numpy的大小_Numpy入门详细教程

序言&#xff1a;python数据科学基础库主要是三剑客&#xff1a;numpy&#xff0c;pandas以及matplotlib&#xff0c;每个库都集成了大量的方法接口&#xff0c;配合使用功能强大。平时虽然一直在用&#xff0c;也看过很多教程&#xff0c;但纸上得来终觉浅&#xff0c;还是需要…

九年级数学解方程50道_初中数学公式中考知识点总结,初三数学上册,九年级数学上册...

初中数学公式中考知识点总结&#xff0c;初三数学上册&#xff0c;九年级数学上册第二十一章 一元二次方程知识点&#xff1a;一元二次方程的解法1、直接开平方法利用平方根的定义直接开平方求一元二次方程的解的方法叫做直接开平方法&#xff0c;2、配方法配方法是一种重要的数…

java时间规划书_【计算机本科补全计划】Java学习笔记(九) Java日期时间

正文之前终于好像仿佛看完了菜鸟教程的Java课程&#xff0c;感觉自己收获颇丰&#xff01;很好&#xff0c;Java看完之后正愁如何开始进阶呢&#xff01;结果发现菜鸟还准备了Java实例这种好东西&#xff01;简直就是教程界的良心啊 &#xff01;&#xff01;&#xff01;没事&…

与40mhz信道不兼容设置_为什么面包板不适合高频电路

01为什么在面包板上玩射频&#xff1f;方便&#xff0c;当然还是方便。面包板是进行一些电子线路实验构建电路方便的平台。多用于普通数字电路和模拟电路。一旦涉及到高频电路&#xff0c;面面包就有很多方面不太适合了。那么到底哪方面不适合&#xff1f;对于高频信号在面包板…

加载gif_搞笑gif:这啥情况啊?笑容加载不出来了?

这无故的小眼神&#xff0c;我也很无奈呀。。。猫和狗对峙&#xff0c;气势上一定不能输几个菜呀&#xff0c;喝成这样&#xff01;这啥情况啊&#xff1f;笑容加载不出来了&#xff1f;高手在民间&#xff01;小青年瞬间变老头&#xff01;丈母娘来家了&#xff0c;说下班就能…