Java容器(2)

P474)Arrays.asList()会生成一个List,它基于一个固定大小的数组,仅支持那些不会改变数组大小的操作。任何会引起底层数据结构的尺寸进行修改的方法都会产生一个UnsupportedOperationException异常,以表示对未获支持操作的调用。

应该把Arrays.asList()的结果作为构造器的参数传递给任何Collection(或者使用addAll()方法,或Collection.addAll()的静态方法),这样可以生成允许使用所有的方法的普通容器。Collections类中的“不可修改”的方法将容器包装到了一个代理中,只要你执行任何试图修改容器的操作,这个代理都会产生UnsupportedOperationException异常。

Iterator和ListIterator的区别

P477)Set

Set(interface) Set不保存重复元素,加入Set的元素必须定义equals()方法以确保对象的唯一性。Set和Collection有完全一样的接口。Set接口不保证维护元素的次序。
HashSet 查找速度块。存入元素必须定义hashCode()。
TreeSet 保持次序的Set,底层为树结构。使用它可以从Set中提取有序的序列。元素必须实现Comparable接口。
LinkedHashList 具有HashSet的查询速度,且内部用链表维护元素的顺序(插入的次序)。元素也必须定义hashCode()方法。

P479)在CompareTo()中比较两个整型数值的大小时,不要用(i1 - i2)作为返回值(除非有unsigned int,但Java没有),因为一个大正数减一个大负数可能会溢出导致返回一个大负数(老实用<、>和==)。

P485)Map

HashMap Map基于散列表的实现(它取代了HashTable)。插入和查询“键值对”的开销是固定的。可以通过构造器设置容量和负载因子。以调整容器的性能。
LinkedHashMap 类似于HashMap,但是迭代遍历它时,取得“键值对”的顺序是其插入次序,或者是最近最少使用(LRU)的次序。只比HashMap慢一点;而在迭代访问是反而更快,因为它使用链表维护内部次序。
TreeMap 基于红黑树的实现。查看“键”或“键值对”时,他们会被排序(次序由Comparable或者Comparator决定)。TreeMap的特点在于,所得到的结构是经过排序的。TreeMap是唯一的带有subMap()方法的Map,它可以返回一个子树。

P489)散列和散列码

Object的hashCode()方法生成散列码默认是使用对象的地址计算散列码。同时,Object.equals()只是比较对象的地址。因此,如果要用自己的类作为HashMap的键,必须同时重载 hashCode()和equals()。

P496)覆盖hashCode()

要想hashCode()实用,它必须速度块,并且必须有意义。也就是说,它必须基于对象的内容生成散列码(应该更关注生成速度,而不是唯一性)。但是通过hashCode()和equals(),必须能够完全确定对象的身份。另外,好的hashCode()应该产生分布均匀的散列码。以下是写出像样hashCode()的基本指导:

1)给个int变量result赋予某个非零值常量

2)为对象内每个有意义的域f计算出一个int散列码c:

boolean c = (f ? 0 : 1)
byte、char、short或int c = (int) f
long c = (int) (f ^ (f >>> 32))
float c = Float.floatToIntBit(f);
double
long l = Double.doubleToLongBits(f);

c = (int) (I ^ (I >>> 32))

Object,其equals()调用这个域的equals() c = f.hashCode()
数组 对每个元素应用上述规则

3)合并计算得到的散列码:   result = 37 × result + c;

4)返回result。

5)检查hashCode()最后生成的结果,确保相同的对象有相同的散列码。

P499)选择接口的不同实现

ArrayList底层由数组支持;而LinkedList是由双向链表实现的,其中的每个对象包含数据的同时还包含指向链表中前一个与后一个元素的引用。因此,如果要经常在表中插入或删除元素,LinkedList就比较适合(LinkedList还有建立在AbstractSequentialList基础上的其他功能);否则,应该使用速度更快的ArrayList。

P507)Math.random()的范围是[0,1);

P512)Collections类内部的静态方法

rotate(List, int distance):所有元素向后移动distance个位置,将末尾的元素循环到前面来。

swap(List, int i, int j):交换List中位置i与位置j的元素。通常比你自己写的块。

P515)设定Collection或Map为不可修改

Collections.unmodifiableCollection(Collection);

Collections.unmodifiableList(List);

Collections.unmodifiableSet(Set);

Collections.unmodifiableSortedSet(Set);

Collections.unmodifiableSortedMap(Map);

无论哪一种,在将容器设为只读之前,必须填入有意义的数据。

P517)快速报错

Java容器有一种保护机制,能够防止多个进程同时修改同一个容器的内容。如果你在迭代遍历某个容器的过程中,另一个进程介入其中,并且插入、删除或修改此容器内的某个对象,那么就会出现问题。

Java容器类类库采用快速报错机制。它会探查容器上的任何除了你的进程所进行的操作以外的所有变化,一旦它发现其他进程修改了容器,就会立刻抛出ConcurrentModificationException异常。

ConcurrentMap、CopyOnWriteArrayList、CopyOnWriteArraySet都使用了可以避免ConcurrentModificationError的技术。

P518)持有引用

java.lang.ref类库包含了一组类,这些类为垃圾回收提供了更大的灵活性。当存在可能会耗尽内存的大对象的时候,这些类显得特别有用。有三个继承自抽象类Reference的类:SoftReference、WeakReference和PhantomReference。

如果想继续持有某个对象的引用,希望以后还能够访问到对象,但是也希望能够允许垃圾回收器释放它,这时就应该使用Reference对象。以Reference对象作为你和普通引用之间的媒介(代理),另外,一定不能有普通的引用指向那个对象,这样就能达到上述目的。

SoftReference、WeakReference、PhantomReference由强到弱排列,对应不同级别的“可获得性”。

使用SoftReference和WeakReference时,可以选择是否要将他们放入ReferenceQueue(用作“回收前的清理工作”的工具)。而PhantomReference只能依赖于ReferenceQueue。

这三个Reference以及WeakHashMap的具体用法。

时间: 2024-10-09 23:45:48

Java容器(2)的相关文章

Java 容器 & 泛型:一、认识容器

Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 容器是Java语言学习中重要的一部分.泥瓦匠我的感觉是刚开始挺难学的,但等你熟悉它,接触多了,也就"顺理成章"地知道了.Java的容器类主要由两个接口派生而出:Collection和Map. 一.Collection vs Collections 首先,Collection 和 Collections 是两个不同的概念.之所以放在一起,是为了更好的比较.Collection是容器层次结构中

Java 容器

在实际问题中我们经常需要处理数据,单纯依靠数组来存储数据对开发来说非常困难,java提供了一套容器来方便我们编程.对java容器有一个整体的了解对我们来说非常重要,这样在需要特定容器时,不会手忙脚乱,本文主要介绍java的一些基本容器,而不要仅知道使用ArrayList.下面的图片是java中的简单容器分类   --图片来自网络 java定义了四种容器类型,List.Set.Queue和Map. 其中List.Set.Queue都实现了Collection接口,下面来看看这4中类型的容器. Co

java容器---集合总结

思考为什么要引入容器这个概念? Java有多种方式保存对象(应该是对象的引用),例如使用数组时保存一组对象中的最有效的方式,如果你想保存一组基本类型的数据,也推荐使用这种方式,但大家知道数组是具有固定尺寸的,你必须事先知道你要需要多少个对象.但是在一般的情况中,你在写程序中并不知道将需要多少个对象,或者是否需要更加复杂的方式来存储对象,因此数组尺寸固定很不爽! 为了解决上述问题,引入了容器的概念.容器提供了完善的方法来保存对象,你可以使用这些工具来解决数量惊人的问题.Java容器类可以自动调整自

Java 容器在实际web项目中应用

前言:在java开发中我们离不开集合数组等,在java中有个专有名词:"容器" ,下面会结合Thinking in Java的知识和实际开发中业务场景讲述一下容器在Web项目中的用法.可结合图片代码了解Java中的容器 备注 :这个地方 ,参考于朝向远方的博客Java容器详解,既然前人总结的这么好,我就直接拿来用,在这里更注重在实际开发中的例子,感谢那些总结的前辈们,辛苦了. 简单的数组例子 Thinking in Java 中并没有把数组归为Java的容器,实际上数组的确不是Java

Java 容器在实际项目中的应用

前言:在java开发中我们离不开集合数组等,在java中有个专有名词:"容器" ,下面会结合Thinking in Java的知识和实际开发中业务场景讲述一下容器在Web项目中的用法.可结合图片代码了解Java中的容器 备注 :这个地方 ,参考于朝向远方的博客Java容器详解,既然前人总结的这么好,我就直接拿来用,在这里更注重在实际开发中的例子,感谢那些总结的前辈们,辛苦了. 简单的数组例子 Thinking in Java 中并没有把数组归为Java的容器,实际上数组的确不是Java

Java面试题-Java容器

一.Java容器分类 Java容器划分为两个概念Collection.Map Collection: 一个独立元素的序列,这些元素都服从一条或多条规则.List必须按照插入的顺序保存元素,不关心是否重复:Set不能有重复元素:Queue一端插入一端输出.所有的Collection都可以用foreach语法遍历 实现:List:ArrayList.LinkedList:   Set:HashSet.TreeSet.LinkedHashSet   Map:HashMap.TreeMap.Linked

java容器集合类

容器就是容纳物品,放置物品的东西,对Java来说,一切皆是对象,他的容器就是能保存java的对象的类.由于数据容器中存放了我们随时可能需要使用到的对象引用,所以一般的数据容器要都要能能提供方便的查询.遍历.修改等基本接口功能. 早期的OOP语言都通过数组的方式来实现对引用集的集中管理和维护.但是数组方式下,数组大小需要提前被确定,并不允许修改大小,导致其作为一种灵活的数据容器的能力的功能大为下降. 为了方便的利用数据容器进行引用的管理,Java中提供了丰富的数据容器以满足程序员多样化的需求. j

java 容器Collection List Set Map概述

对JAVA的集合的理解是想对于数组 数组是大小固定的,并且同一个数组只能存放类型一样的数据(基本类型/引用类型) JAVA集合可以存储和操作数目不固定的一组数据. 所有的JAVA集合都位于 java.util包中! JAVA集合只能存放引用类型的的数据,不能存放基本数据类型. JAVA集合主要分为三种类型: Set(集) List(列表) Map(映射) Collection 接口 Collection是最基本的集合接口,声明了适用于JAVA集合(只包括Set和List)的通用方法. Set 和

Java 容器相关知识全面总结

Java实用类库提供了一套相当完整的容器来帮助我们解决很多具体问题.因为我本身是一名Android开发者,包括我在内很多安卓开发,最拿手的就是ListView(RecycleView)+BaseAdapter+ArrayList三剑客, 平时接触使用的容器也只有ArrayList和HashMap.导致对于整个Java容器体系的掌握和使用还停留在很浅的层面.省不足而思改进,那么跟着我来总结一下Java容器的相关知识吧. 结构 java容器类的继承结构 具体介绍 迭代器 Collection Lis

java 容器 arraylist 使用方法

1. ArrayList概述: ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAccess, Cloneable, java.io.Serializable这些接口. ArrayList 继承了AbstractList,实现了List.它是一个数组队列,提供了相关的添加.删除.修改.遍历等功能. ArrayList 实现了RandmoAccess接口,即提供了随机访问功能.Rand