基于java集合中的一些易混淆的知识点(详解)

(一) collection和collections

这两者均位于java.util包下,不同的是:

collection是一个集合接口,有ListSet等常见的子接口,是集合框架图的第一个节点,,提供了对集合对象进行基本操作的一系列方法。

常见的方法有:

boolean add(E e) 往容器中添加元素;int size() 返回collection的元素数;boolean isEmpty() 判断此容器是否为空; boolean contains(Object o) 如果此collection包含指定的元素,则返回true,,这里会用到equals()方法;boolean remove(Object o) 移除指定元素的实例;等。

而collections是一个包装类,它包含有各种有关集合操作的静态多态方法,它包含在 collection 上操作的多态算法,即“包装器”,包装器返回由指定 collection 支持的新 collection,以及少数其他内容。

常见的方法有:

void sort(List) 对List的内容进行排序。

这里要注意的是,(ps:以下有关sort()的说明摘自浅谈对象数组或list排序及Collections排序原理,对List及Collection排序追本溯源,写得很清晰)

这个sort()函数中的排序主体是Arrays.sort(),

@SuppressWarnings("unchecked")
public static <T extends Comparable<? super T>> void sort(List<T> list) {
 Object[] array = list.toArray();
 Arrays.sort(array);
 int i = 0;
 ListIterator<T> it = list.listIterator();
 while (it.hasNext()) {
  it.next();
  it.set((T) array[i++]);
 }
}

而Arrays.sort()中,可以看出是通过ComparableTimSort.sort(Object[] a)实现的:

public static void sort(Object[] array) {
 // BEGIN android-changed
 ComparableTimSort.sort(array);
 // END android-changed
} 

static void sort(Object[] a)到static void sort(Object[] a, int lo, int hi)到private static void binarySort(Object[] a, int lo, int hi, int start)。在binarySort中用于大小比较部分为:

Comparable<Object> pivot = (Comparable) a[start];
int left = lo;
int right = start;
assert left <= right; 

while (left < right) {
 int mid = (left + right) >>> 1;
 if (pivot.compareTo(a[mid]) < 0)
  right = mid;
 else
  left = mid + 1;
}

二分查找中比较大小部分使用了Comparable接口的唯一一个方法:compareTo(),所有如果自定义的类装载到容器中需要进行比较的时候,要实现Comparable接口或继承Comparator类,并重写compareTo()方法。

int binarySearch(List object) 对于顺序的List容器,采用折半查找法查找指定对象;void reverse(List) 对List的容器内的对象进行逆序排列;等。

(二)Iterator和Iterable

首先,Iterable位于java.lang包下,Iterator位于java.util包下。在集合框架中,Iterator接口中定义了一下三个方法:boolean hasNext();E next();void remove()。而Iterable中只定义了一个方法:iterator(),返回值为实现了Iterator接口的的一个对象。Collection继承了Iterable这个超级接口,故所有的集合框架中的实现类都具有iterator()这个方法,而多态让Iterator的引用可以访问到当前集合中实现了Iterator的那部分(即那三个方法)。此时如果需要删除元素,由于Iterator对这个集合操作时完成了锁定,在用Iterator循环遍历的过程中只能使用Iterator的remove()方法,而不能使用Collection自己的remove(Object)方法。

那么为什么一定要实现Iterable接口,为什么不直接实现Iterator接口呢,这样就可以让集合类直接继承这三个方法?

看一下JDK中的集合类,比如List一族或者Set一族,都是实现了Iterable接口,但并不直接实现Iterator接口。

仔细想一下这么做是有道理的。

因为Iterator接口的核心方法next()或者hasNext() 是依赖于迭代器的当前迭代位置的。

如果Collection直接实现Iterator接口,势必导致集合对象中包含当前迭代位置的数据(指针)。

当集合在不同方法间被传递时,由于当前迭代位置不可预置,那么next()方法的结果会变成不可预知。

除非再为Iterator接口添加一个reset()方法,用来重置当前迭代位置。

但即时这样,Collection也只能同时存在一个当前迭代位置。

而Iterable则不然,每次调用都会返回一个从头开始计数的迭代器。

多个迭代器是互不干扰的。

以上这篇基于java集合中的一些易混淆的知识点(详解)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

时间: 2016-09-05

浅谈Java线程并发知识点

发布:一个对象是使它能够被当前范围之外的代码所引用: 常见形式:将对象的的引用存储到公共静态域:非私有方法中返回引用:发布内部类实例,包含引用. 逃逸:在对象尚未准备好时就将其发布. 不要让this引用在构造函数中逸出.例,在构造函数中启动线程,线程会包含对象的引用. 同步容器:对容器的所有状态进行穿行访问,Vector.Hashtable,Cllections.synchronizedMap|List 并发容器:ConcurrentHashMap,CopyOnWriteArrayList,Co

Java final 修饰符知识点总结(必看篇)

final从字面上理解含义为"最后的,最终的".在Java中也同样表示出此种含义. final可以用来修饰变量(包括类属性.对象属性.局部变量和形参).方法(包括类方法和对象方法)和类. 1. final修饰类: final修饰类即表示此类已经是"最后的.最终的"含义.因此,用final修饰的类不能被继承,即不能拥有自己的子类. 如果视图对一个已经用final修饰的类进行继承,在编译期间或发生错误. 2. final修饰方法: final修饰的方法表示此方法已经是&

Java知识点归纳 —给Java新手的一些建议(新手必看)

写这篇文章的目的是想总结一下自己这么多年来使用java的一些心得体会,主要是和一些java基础知识点相关的,所以也希望能分享给刚刚入门的Java程序员和打算入Java开发这个行当的准新手们,希望可以给大家一些经验,能让大家更好学习和使用Java. 这次介绍的主要内容是和J2SE相关的部分,另外,会在以后再介绍些J2EE相关的.和Java中各个框架相关的内容. 经过这么多年的Java开发,以及结合平时面试Java开发者的一些经验,我觉得对于J2SE方面主要就是要掌握以下的一些内容. 1. JVM相

Java面试问题知识点总结

本篇文章会对面试中常遇到的Java技术点进行全面深入的总结(阅读本文需要有一定的Java基础:若您初涉Java,可以通过这些问题建立起对Java初步的印象,待有了一定基础后再后过头来看收获会更大),喜欢的朋友可以参考下. 1. Java中的原始数据类型都有哪些,它们的大小及对应的封装类是什么? (1)boolean boolean数据类型非true即false.这个数据类型表示1 bit的信息,但是它的大小并没有精确定义. <Java虚拟机规范>中如是说:"虽然定义了boolean这

Java中面向对象的知识点总结

一.对象和类的概念 类:对具有相同属性和方法的一类事物的抽象. 对象:具体的某一事物,代表自身的一些属性和方法. 二.类(对象)之间的关系 关联(组合.聚合),继承,依赖.实现 三.面向对象设计思想 面向对象--->考虑哪些类,对象--->类和对象有属性.方法----->类和类之间的关系 四.重载.重写和隐藏 1). 重载(overload): 方法重载就是多个方法名称相同但是参数类型或者参数个数不同的方法,与返回值类型和修饰符无关 class Test { public int tes

Java中的小知识点总结

一.声明局部变量是的一些特性和规则(1)声明的局部变量是不会被默认初始化的,成员变量则是会被默认初始化的.例如: 复制代码 代码如下: class Demo {         public static void main(String[] args) {           String s;           System.out.println(s);     }} 上面的这段示例代码中,直接输出s是错误的,连编译都不同通过,因为在main方法中声明s,这时s是局部变量,不会被默认初始

面向对象编程:Java中的抽象数据类型

文章来源:互联网 作者:PaleSting/CSDN 在本文中,我们将考察Java中的数据类型,但是我们将介绍抽象数据类型(ADT)的概念.我们还将通过介绍Java Collections Framework(Java 集合架构)来学习Java定义的一些ADT. ADT 一个ADT是一个仅由保存的数据类型和可能在这个数据类型上进行的操作定义的.开发者们只能通过ADT的操作方法来访问ADT的属性,而且他们不会知道这个数据类型内部各种操作是如何实现的. 在Java中,我们常常使用一个接口来给出一个操

Java中多态性的实现方式

什么是多态 面向对象的三大特性:封装.继承.多态.从一定角度来看,封装和继承几乎都是为多态而准备的.这是我们最后一个概念,也是最重要的知识点. 多态的定义:指允许不同类的对象对同一消息做出响应.即同一消息可以根据发送对象的不同而采用多种不同的行为方式.(发送消息就是函数调用) 实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法. 多态的作用:消除类型之间的耦合关系. 现实中,关于多态的例子不胜枚举.比方说按下

Java中重载与重写的对比与区别

Java中重载与重写的区别 首先我们来讲讲:重载(Overloading) (1) 方法重载是让类以统一的方式处理不同类型数据的一种手段.多个同名函数同时存在,具有不同的参数个数/类型. 重载Overloading是一个类中多态性的一种表现. (2) Java的方法重载,就是在类中可以创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义. 调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法, 这就是多态性. (3) 重载的时候,方法名要一样,但是参数类型和个数不一样

深入理解Java中的final关键字_动力节点Java学院整理

Java中的final关键字非常重要,它可以应用于类.方法以及变量.这篇文章中我将带你看看什么是final关键字?将变量,方法和类声明为final代表了什么?使用final的好处是什么?最后也有一些使用final关键字的实例.final经常和static一起使用来声明常量,你也会看到final是如何改善应用性能的. final关键字的含义? final在Java中是一个保留的关键字,可以声明成员变量.方法.类以及本地变量.一旦你将引用声明作final,你将不能改变这个引用了,编译器会检查代码,如

java中hashCode方法与equals方法的用法总结

首先,想要明白hashCode的作用,必须要先知道Java中的集合. 总的来说,Java中的集合(Collection)有两类,一类是List,再有一类是Set. 前者集合内的元素是有序的,元素可以重复:后者元素无序,但元素不可重复. 那么这里就有一个比较严重的问题了:要想保证元素不重复,可两个元素是否重复应该依据什么来判断呢? 这就是Object.equals方法了.但是,如果每增加一个元素就检查一次,那么当元素很多时,后添加到集合中的元素比较的次数就非常多了. 也就是说,如果集合中现在已经有

Java中的length和length()深入分析

在开始本文前先考虑以下一个问题 在不使用任何带有自动补全功能IDE的情况下,如何获取一个数组的长度?以及,如何获取一个字符串的长度? 这个问题我问过不同水平的程序员,包括初级和中级水平的.他们都不能准确而自信地回答这个问题(如果你能很准确很自信的回答这个问题,那么证明针对这一知识点你比大多数中级程序员掌握的好).由于现在很多IDE都有代码补全功能,这使得开发人员在很多问题上都理解的很肤浅. 上面问题的正确回答姿势应该是这样的: int[] arr = new int[3]; System.out

探索Java中的equals()和hashCode()方法_动力节点Java学院整理

equals()和hashCode()区别?  equals():反映的是对象或变量具体的值,即两个对象里面包含的值--可能是对象的引用,也可能是值类型的值.  hashCode():计算出对象实例的哈希码,并返回哈希码,又称为散列函数.根类Object的hashCode()方法的计算依赖于对象实例的D(内存地址),故每个Object对象的hashCode都是唯一的:当然,当对象所对应的类重写了hashCode()方法时,结果就截然不同了. 之所以有hashCode方法,是因为在批量的对象比

Java中的接口和抽象类用法实例详解

本文实例讲述了Java中的接口和抽象类用法.分享给大家供大家参考,具体如下: 在面向对象的概念中,我们知道所有的对象都是通过类来描绘的,但是并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类往往用来表征我们在对问题领域进行分析. 设计中得出的抽象概念,是对一系列看上去不同,但是本质上相同的具体概念的抽象,我们不能把它们实例化(拿不出一个具体的东西)所以称之为抽象. 比如:我们要描述"水果",它就是一个抽象,它有质量.体积等