Java集合类学习记录

被标记为transient的属性在对象被序列化的时候不会被保存
int[] arr1 = {1, 2, 3, 4, 5};
int[] arr2 = Arrays.copyOf(arr1, new_length);//Arrays是数组的工具类
//ArrayList的转化为静态数组的toArray方法就是这个原理
//ArrayList的扩容原理也是Arrays.copyOf()方法
//新建了一个数组
定义一个数组int[] a={3,1,4,2,5}; int[] b=a; 数组b只是对数组a的又一个引用,即浅拷贝。
如果改变数组b中元素的值,其实是改变了数组a的元素的值
要实现深度复制,可以用clone或者System.arrayCopy
如下面的代码

1 int[] a={3,1,4,2,5};
2 int[] b=a.clone();
3 b[0]=10;
4 System.out.println(b[0]+" "+a[0]);
输出为10 3
可见改变了b的值,但是没有改变a的元素的值

除了不同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。HashMap不是线程安全的,如果想要线程安全的HashMap,可以通过Collections类的静态方法synchronizedMap获得线程安全的HashMap。

Map map = Collections.synchronizedMap(new HashMap());

在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可
以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链

表的结合体。它之所以有相当快的查询速度主要是因为它是通过计算散列码来决定存储的位置。

HashMap中主要是通过key的hashCode来计算hash值的,只要hashCode相同,计算出来的hash值就一样。如果存储的对象对多了,就有可能不同的对象所算出来的hash值是相同的,这就出现了所谓的hash冲突。学过数据结构的同学都知道,解决hash冲突的方法有很多,HashMap底层是通过链表来解决hash冲突的。

当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值,根据hash值得到这个元素在数组中

的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,

新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置

上。

HashMap其实就是一个Entry数组,Entry对象中包含了键和值,其中next也是一个Entry对象,它就是用来处理hash冲突的,形成一个链表。

loadFactor加载因子是表示Hsah表中元素的填满的程度,

必须在 "冲突的机会"与"空间利用率"之间寻找一种平衡与折衷. 这种平衡与折衷本质上是数据结构中有名的"时-空"矛盾的平衡与折衷.

  如果机器内存足够,并且想要提高查询速度的话可以将加载因子设置小一点;相反如果机器内存紧张,并且对查询速度没有什么要求的话可以将加载因子设置大一点。不过一般我们都不用去设置它,让它取默认值0.75就好了。

 // 若“key为null”,则将该键值对添加到table[0]中。HashMap中则通过h&(length-1)的方法来代替取模,同样实现了均匀的散列,但效率要高很多,这也是HashMap对Hashtable的一个改进。
length为2的n次方,为偶数,length-1为奇数,最后一位为1,(h为hash值)

length取2的整数次幂,是为了使不同hash值发生碰撞的概率较小,这样就能使元素在哈希表中均匀地散列。如果这两个 Entry 的 key 通过 equals 比较返回 true,新添加 Entry 的 value 将覆盖集合中原有 Entry 的 value,但key不会覆盖。如果这两个 Entry 的 key 通过 equals 比较返回 false,新添加的 Entry 将与集合中原有 Entry 形成 Entry 链,而且新添加的 Entry 位于 Entry 链的头部当HashMap中的元素越来越多的时候,hash冲突的几率也就越来越高,因为数组的长度是固定的。所以为了提高查询的效率,就要对HashMap的数组进行扩容,数组扩容这个操作也会出现在ArrayList中,这是一个常用的操作,而在HashMap数组扩容之后,最消耗性能的点就出现了:原数组中的数据必须重新计算其在新数组中的位置,并放进去,这就是resize。扩容是需要进行数组复制的,复制数组是非常消耗性能的操作,所以如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能

LinkedList底层的数据结构是基于双向循环链表的,且头结点中不存放数据,如下:

LinkedList<String> list = new LinkedList<String>();
 2         list.add("First");
 3         list.add("Second");
 4         list.add("Thrid");
 5        System.out.println(list);
 6         ListIterator<String> itr = list.listIterator();
 7         while (itr.hasNext()) {
 8            System.out.println(itr.next());
 9        }
				
时间: 2024-10-24 00:59:13

Java集合类学习记录的相关文章

Java集合类汇总记录-- apache.commons4(TreeList)

通常,Tree是Tree,List是List,两者不太可能混在一起.但apache-commons库却用tree实现了实现了List的接口,也就是TreeList类.与标准的LinkedList相比,TreeList稍微浪费一点空间,但常用操作的时间复杂度均降低到了O(log N),值得在开发中权衡利弊.合理应用. 内部数据结构 TreeList内部包含了一个Thread AVL Tree.AVL Tree很常见了,是一种典型的Balanced Binary Tree,但下面简单介绍下Threa

Java集合类汇总记录--guava篇

BiMap HashBiMap<K,V> 实现了两份哈希表数据结构(本类独立实现),分别负责两个方向的映射. EnumBiMap<K,V> 两个EnumMap对象分别负责两个方向的映射. EnumHashBiMap<K,V> 一个EnumMap对象负责K到V映射,一个HashMap对象负责V到K的影身. MultiMap HashMultimap<K,V> 使用HashMap<K,HashSet<V>>对象实现. TreeMultim

Java集合类汇总记录--JDK篇

接口类图 Java Collection由两套并行的接口组成,一套是Collection接口,一套是Map接口.如下图 公共抽象类AbstractCollection 要求派生类实现iterator()方法,AbstractCollection根据得到的Iterator实现所有可以支持的方法,比如remove().contains().toArray().toString()等. 当然,Map系列的类并不从AbstractCollection派生. List实现 AbstractList 要求子

Java设计模式学习记录-桥接模式

前言 这次介绍结构型设计模式中的第二种模式,桥接模式. 使用桥接模式的目的就是为了解耦,松散的耦合更利于扩展,但是会增加相应的代码量和设计难度. 桥接模式 桥接模式是为了将抽象化与实现化解耦,让二者可以独立地变化.方便对每一部分的扩展,以及单独的维护.抽象化的一方与实现化的一方之间建立一个桥梁,这样两者的依赖关系就可以通过这个桥梁来建立了. 举例 三个小动物要过河,分别是小猪,小鸡,小马,小猪要去河对面的空地晒太阳,小鸡要去河对面的小树林里找虫子吃,小马要去河对面的草地里吃草.那么它们三个都要经

Java设计模式学习记录-装饰模式

前言 装饰模式也是一种结构型模式,主要是目的是相对于类与类之间的继承关系来说,使用装饰模式可以降低耦合度.JDK中有不少地方都使用到了装饰模式,例如Java的各种I/O流,javax.swing包中一些图形界面构件功能的增强等地方都运用了装饰模式. 装饰模式 定义 装饰模式的定义是:在不改变原类文件以及不使用继承的情况下,动态的扩展一个对象的功能.装饰模式是通过创建一个包装对象来实现的,也就是用装饰来包裹真实的对象. 举例 还是老规矩,举例说明,在给亲朋好友过生日时会买生日蛋糕,然后生日蛋糕又有

Java设计模式学习记录-迭代器模式

前言 这次要介绍的是迭代器模式,也是一种行为模式.我现在觉得写博客有点应付了,前阵子一天一篇,感觉这样其实有点没理解透彻就写下来了,而且写完后自己也没有多看几遍,上次在面试的时候被问到java中的I/O的各种实现用到了什么设计模式,我愣是想半天没想出来了,人家还给提示了我也没想出来,最后还是面试官给出的答案,是装饰模式,听到答案后就恍然大悟了,前两天刚看了装饰模式,还写下了I/O操作中的各种类都是用到了装饰模式,后来想想两方面原因造成的当时没回答出来,一是面试时紧张就容易想不起来,二是对设计模式

Java设计模式学习记录-状态模式

前言 状态模式是一种行为模式,用于解决系统中复杂的对象状态转换以及各个状态下的封装等问题.状态模式是将一个对象的状态从该对象中分离出来,封装到专门的状态类中,使得对象的状态可以灵活多变.这样在客户端使用时无需关心对象的状态,可以实现自身的一致性处理.最近工作有些忙,更新博客慢了.还是要严格要求自己的,抽时间也要坚持学习. 状态模式 概念介绍 状态模式允许一个对象在其状态改变时,改变它的行为,对象看起来似乎修改了它的类. 想要在改变自身状态时改变对象行为,最直接的方法就是在代码中将所有可能发生的情

Java设计模式学习记录-单例模式

前言 已经介绍和学习了两个创建型模式了,今天来学习一下另一个非常常见的创建型模式,单例模式. 单例模式也被称为单件模式(或单体模式),主要作用是控制某个类型的实例数量是一个,而且只有一个. 单例模式 单例模式的实现方式 实现单例模式的方式有很多种,大体上可以划分为如下两种. 外部方式 在使用某些全局对象时,做一些“try-Use”的工作.就是如果要使用的这个全局对象不存在,就自己创建一个,把它放到全局的位置上:如果本来就有,则直接拿来使用. 内部实现方式 类型自己控制正常实例的数量,无论客户程序

Java虚拟机学习--记录运行时数据区域

为方便后面学习的理解,记录一下! 运行时数据区 1.线程共享 1.1方法区(Method Area) 1.1.1运行时常量池(Runtime Constant Pool) 1.2堆(Heap) 2.线程私有 2.1虚拟机栈(VM Stack) 2.2本地方法栈(Native Method Stack) 2.3程序计数器(Program Counter Register) 3.直接内存(Direct Memory) 虚拟机栈: 线程私有,生命周期与线程同步,用来执行Java方法. 每个java方法