java容器类继承_JAVA容器 - weslie - OSCHINA - 中文开源技术交流社区

一、 数组

1、数组是保存一组对象的最有效的方式。但数组有固定的尺寸而受限(p216)

2、数组与其他种类的容器之间的区别有三方面:效率、类型和保存基本类型的能力。在Java中,数组是一种效率最高的存储和随机访问对象引用序列的方式。数组就是一个简单的线性序列,这使得元素访问非常快速。但是为这种速度所付出的代价就是数组对象的大小被固定,并且在其生命周期中不可改变。

3、无论使用哪种类型的数组,数组标识符其实只是一个引用,指向在堆中创建的一个真实对象,这个(数组)对象用以保存指向其他对象的引用。

4、对象数组和基本类型数组在使用上几乎是相同的,唯一的区别就是对象数组保存的是引用,基本类型数组直接保存基本类型的值。新建一个对象数组未赋值时自动初始化为null,同样基本类型的数组如果是数值型的,就被自动初始化为0,如果是字符型(char)的,就被自动初始化为(char)O,如果是布尔型(boolean),就被自动初始化为false。

5、多维数组

//创建多维数组

public static void main(String[] args) {

int[][] a = {{ 1, 2, 3}, { 4, 5, 6}};

System.out.println(Arrays.deepToString(a));

//deepToString返回指定数组“深层内容”的字符串表示形式。如果数组包含作为元素的其他数组,

//则字符串表示形式包含其内容等。此方法是为了将多维数组转换为字符串而设计的。

int[][][] b = new int[2][2][4];

System.out.println(Arrays.deepToString(b));

}

public static void main(String[] args) {

Integer[][] a;

a = new Integer[6][];

for (int i = 0; i < a.length; i++) {

a[i] = new Integer[3];

for (int j = 0; j < a[i].length; j++)

a[i][j] = i * j; // Autoboxing

}

System.out.println(Arrays.deepToString(a));

//Output: [[0, 0, 0], [0, 1, 2], [0, 2, 4], [0, 3, 6], [0, 4, 8], [0, 5, 10]]

}

6、数组与泛型

通常,数组与泛型不能很好地结合。你不能实例化具有参数化类型的数组,擦除会移除参数类型信息,而数组必须知道它们所持有的确切类型,以强制保证类型安全。但是,你可以参数化数组本身的类型:

//类泛型

class ClassParameter {

public T[] f(T[] arg) {

return arg;

}

}

class MethodParameter {

// 方法泛型

public static T[] f(T[] arg) {

return arg;

}

}

public class ParameterizedArrayType {

public static void main(String[] args) {

Integer[] ints = { 1, 2, 3, 4, 5 };

Double[] doubles = { 1.1, 2.2, 3.3, 4.4, 5.5 };

Integer[] ints2 = new ClassParameter().f(ints);

Double[] doubles2 = new ClassParameter().f(doubles);

ints2 = MethodParameter.f(ints);

doubles2 = MethodParameter.f(doubles);

System.out.println(Arrays.deepToString(ints2));

}

}

7、Arrays实用功能

Arrays有六个基本方法:

(1)equals()用于比较两个数组是否相等(deepEquals()用于多维数组),

(2)fill()

(3)sort()用于对数组排序

(4)binarySearch()使用二分搜索法在已经排序的数组中查找元素,必须在进行此调用前对数组进行排序,如果没有对数组进行排序,则结果是不确定的。如果数组包含多个带有指定值的元素,则无法保证找到的是哪一个。如果元素包含在数组中,则返回搜索元素的索引,否则返回搜索键的索引(好像就是得到搜索数组的长度的负值);否则返回(-(插入点) - 1)。插入点 被定义为将键插入数组的那一点:即第一个大于此键的元素索引,如果数组中的所有元素都小于指定的键,则为a.length。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0 。

(5)toString()产生数组的String表示

(6)hashCode()产生数组的散列码

(7)asList()转变成List容器

(8)copyOf

(9)System.arraycopy(),该方法不会执行自动包装和自动拆包,两个数组必须具有相同的确切类型。

8、利用Comparable进行比较

利用该接口来进行比较很简单,只需实现该接口然后实现compartTo方法即可。如果当前对象小于参数则返回负值,如果相等则返回零,如果当前对象大于参数则返回正值。

二、 集合类

集合类,也称Java容器类

1、Java容器类类库的用途是“保存对象”,并将其划分为两个不同的概念。(p219)

(1)Collection。该容器类类库包括List、Set、Queue。List必须按照插入的顺序保存元素,Set不能有重复的元素,Queue按照排队规则来确定对象产生的顺序(通常与他们被插入的顺序相同)。

(2)Map。它被称为“关联数组”,因为它将某些对象与另外一些对象关联在一了一起。Map是强大的编程工具。

2、Collection接口概括了序列的概念(一种存放一组对象的方式。)(p219)

3、每个java.util容器都有其自己的Abstract类,它们提供了该容器的部分实现。

4、为了创建只读的Map,可以继承AbstractMap并实现entrySet(),

为了创建只读的Set,可以继承AbstractSet并实现iterator()和size(),

为了创建只读的List,可以继承AbstractList并实现get()和size()。

3、在java.util包中的Arrays和Collections类中都有很多实用方法。

public static void main(String[] args) {

Collection collection = new ArrayList(Arrays.asList(1,2,3,4,5,6,7,8,9,0));

Integer[] moreInts = {43,82,98,90,21};

//Arrays.asList()方法接收一个数组或是一个用逗号分隔的元素列表(使用可变参数) --> 转成List对象

collection.addAll(Arrays.asList(moreInts));

//Collections.addAll()方法接受一个Collection对象,以及一个数组或者是可变参数,将元素添加到Collection中

Collections.addAll(collection, 11,12,34,843,90,80,3);

Collections.addAll(collection, moreInts);

List list = Arrays.asList(73,92,84,93,26,78,79);

list.set(1, 0);//将索引为1的元素的值修改为0

}

4、完整的容器分类

a5231f0113a390c2eec9934f9a43721b.png

由上图可以看出,Hashtable、Vector、Stack的特征是,它们是过去遗留下来的类,目的是为了支持老的程序(最好不要在新的程序中使用它们)

不同类型的Queue只在它们接受和产生数值的方式上有所差异

List

1、ArrayList,它长于随机访问元素,但是在List的中间插入和移除元素时比较慢(p223)

2、LinkedList,它通过代价较低的在List中间进行的插入和删除操作,提供了优化的顺序访问。但是在随机访问方面相对比较慢,但是它的特性集较ArrayList更大。

LinkedList还添加了可以使其用作栈、队列或双端队列的方法。(p228)

LinkedList具有能够直接实现栈的所有功能的方法

3、如果要进行大量的随机访问,就使用ArrayList;如果要经常从表中间插入或删除元素,则应该使用LinkedList。(p245)

4、Arrays.asList会生成一个List,它基于一个固定大小的数组,仅支持那些不会改变数组大小的操作,因此add等操作方法会抛出一个不可选操作的异常。我们应该吧Arrays.asList的结果作为参数传递给任何Collection(或者使用addAll()方法,或Collections.addAll()静态方法),这样可以生成允许使用所有的方法的普通容器。

Stack

1、“栈”通常是指“后进先出”(LIFO)的容器。有时栈也被称为叠加栈,因为最后“压入”栈的元素,第一个弹出栈。

Set

1、

Set不能保存重复的元素,Set中最常被使用的是测试归属性,你可以很容易地询问某个对象是否在某个Set中。正因为如此,查找就成为了Set中最重要的操作。Set具有与Collection完全一样的接口,因此没有任何额外的功能,不像List会有两个不同的List。实际上Set就是Collection,只是行为不同。Set是基于对象的值来确定归属的  (p231)

(1)HashSet无序的,查找元素最快;HashSet使用的是相当复杂的方式来存储元素的(p222),出于速度的原因,HashSet使用了散列。HashSet所维护的顺序与TreeSet或LinkedHashSet都不同,因为他们的实现具有不同的元素的存储方式。TreeSet将元素存储在红-黑树数据结构中,而HashSet使用的是散列函数,LinkedHashSet因查询速度的原因,也使用了散列,但是看起来它使用了链表来维护元素的插入顺序。

(2)TreeSet它按照比较结果的升序保存对象,保持元素处于排序状态;

(3)LinkedHashSet,它按照被添加的顺序保存对象,以插入顺序保存元素。

423aeda42bee34ec240519eed16fca4b.png

Map

1、Map也被称为关联数组,就像一个简单的数据库。

Map是一种将对象(而非数字)与对象相关联的设计。HashMap设计用来快速访问;而TreeMap保持“键”始终处于排序状态,所以没有HashMap快。LinkedHashMap保持元素插入的顺序,但是也通过散列提供了快速访问能力。

如何解释散列?(p245)

Map保存的顺序并不是他们插入的顺序;

HashMap也提供了最快的查找技术,无序保存,键和值在Map中的保存顺序并不是他们的插入顺序,因为HashMap实现使用的是一种非常快的算法来控制顺序;

TreeMap按照比较结果的升序保存键;

LinkedHashMap按插入顺序保存键,同时还保留了HashMap的查询速度。

Queue

1、Queue:队列是一个典型的先进先出(FIFO)的容器。即从容器的一端放入事物,从另一端取出,并且事物放入容器的顺序与取出的顺序是相同的。队列常被当作一种可靠的将对象从程序的某个区域传输到另一个区域的途径。

队列在并发编程中特别重要,因为他们可以安全地将对象从一个任务传输到另一个任务。

LinkedList提供了方法以支持队列的行为,并且它实现了Queue的接口,(p236)

各种Queue以及栈的行为,由LinkedList提供支持(p245)

public static void main(String[] args) {

Queue queue = new LinkedList();

Random rand = new Random(47);

for(int i=0; i<10; i++){

queue.offer(rand.nextInt(i + 10));//offer方法是一个元素插入到队尾或者返回false

}

while(queue.peek() != null){//peek获取栈顶第一元素,pop弹栈,push压栈

System.out.println(queue.remove() + " ");

}

}

2、先进先出描述了最典型的队列规则。队列规则是指在给定一组队列中的元素的情况下,确定下一个弹出队列的元素的规则。

先进先出声明的是下一个元素应该是等待时间最长的元素。

优先级队列声明下一个弹出元素是最需要的元素(具有最高的优先级)。(p237)

迭代

1、迭代器也是一种设计模式,迭代器通常被称为轻量级对象:创建它的代价小。(p226)

2、Java的Iterator只能单向移动

public static void main(String[] args) {

Map map = new HashMap();

map.put(100, "jack");

map.put(200, "marry");

map.put(300, "sisi");

/* 1、Set迭代 */

System.out.println("******Set迭代******");

Set set = new HashSet();

Collections.addAll(set, 100,200,300);

Iterator setIt = set.iterator();

while (setIt.hasNext()) {

Integer key = setIt.next();

System.out.print(key + "\t");

}

/* 2、Map迭代一:keySet */

System.out.println("\r\r******Map迭代:keySet******");

Set keySet = map.keySet();// 将Map集合的Key转成Set集合,再通过key获取对应的值

Iterator map1It = keySet.iterator();

while (map1It.hasNext()) {

Integer key = map1It.next();

String value = map.get(key);

System.out.print(key + "-" + value + "\t");

}

/* 3、Map迭代二:entrySet */

System.out.println("\r\r******Map迭代:entrySet******");

Set> entrySet = map.entrySet();

Iterator> it = entrySet.iterator();

while (it.hasNext()) {

Entry entry = it.next();

Integer key = entry.getKey();

String value = entry.getValue();

System.out.print(key + "" + value + "\t");

}

/* 4、Map迭代三:增强for循环 */

System.out.println("\r\r******Map迭代:增强for循环******");

for(Integer key : map.keySet()){//注意这里Key的类型是由map的泛型决定,否则是object

System.out.print(key + ":" + map.get(key) + "\t");

}

/* 5、增强for循环迭代List */

List newDeptList = new ArrayList();

List deptName = new ArrayList();

for(Department dept:deptList){

if(!deptName.contains(dept.getDepartmentName())){

deptName.add(dept.getDepartmentName());

newDeptList.add(dept);

}

}

}输出结果:

9f2925c3dac4b06aa9a85e5cc7cccc43.png

3 、ListIterator

ListIterator是一个更加强大的Iterator的子类型,是一个接口,它只能用于各种List类的访问。Iterator只能向前移动,但是ListIterator可以双向移动。它还可以产生相对于迭代器在列表中指向的当前位置的前一个和后一个元素的索引,并且可以使用set()方法替换它访问过的最后一个元素。你可以通过调用listIterator()方法产生一个指向List开始处的ListIterator,并且还可以通过调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处的ListIterator。

public static void main(String[] args) {

List list = new ArrayList();

Collections.addAll(list, "java","c","c++","oracle","mysql");

ListIterator it = list.listIterator();

while(it.hasNext()){

System.out.println(it.next() + " " + it.nextIndex() + ", " + it.previousIndex() + ";");

}

System.out.println();

//Backwards

while(it.hasPrevious()){

System.out.print(it.previous() + " ");//previous前一个元素

}

}

另外还可以通过ListIterator实现动态向List中添加数据

public static void main(String[] args) {

List list = new ArrayList();

Collections.addAll(list, "jack","marry","sisi");

/* 1、使用iterator动态添加数据 */

Iterator it = list.iterator();

while(it.hasNext()){

String key = it.next();//这行在第二次循环时会出错,因为在创建迭代器的时候(it = list.iterator()),list通知迭代器的是长度为3,而在执行完list.add(“qq”)时,list长度已经是4,但是没有及时通知迭代器,所以会出错。

System.out.print(key+"\t");

//list.add("qq");//迭代时向List集合中添加数据,在第一次循环最后会想list中添加数据,在验证iterator动态添加数据时需吧这行注释去掉

}

System.out.println("\r**************************");

/* 2、使用ListIterator动态添加数据 */

ListIterator it2 = list.listIterator();//ListIterator

while (it2.hasNext()) {

String key = it2.next();

System.out.print(key + "\t");

// 动态通知迭代器,加入了新元素,从而迭代器自动通知List集合。

it2.add("qq");//现在添加进去的数据,在下次迭代时才会被迭代出来

}

System.out.println("\r**************************");

/* 3、再次对集合迭代,验证数据是否被添加进去 */

ListIterator it3 = list.listIterator();

while (it3.hasNext()) {

String key = it3.next();

System.out.print(key + "\t");

}

}

输出结果:

14890fc47b39aa24412cffeea8931edb.png

三、 总结

1、新程序中不应该使用过时的Vector、Hashtable 和Stack。(p245)

2、Java容器简图(p246)

3、程序的输出是从Object默认的toString()方法产生的,该方法将打印类名,后面跟随该对象的散列码的无符号十六进制表示(这个散列码是通过hashCode()方法产生的)。你将在第17章中了解到有关散列码的内容(p218)

4、优化是一个很棘手的问题,最好的策略就是置之不顾,直到你发现需要担心它了(尽管理解这些问题总是一种好的思路)

5、通过针对接口而非具体实现来编码,我们的代码可以应用与更多的对象类型。(p239)

6、将保持不变的事物与会发生改变的事物相分离

7、Collections常用方法(不包括Object继承而来的方法),下列方法也是可通过Set或List执行的所有操作(List还有额外的功能),Map不是继承自Collection会另行介绍。

68a386223957b1b049ed6aacd7cbfe01.png

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

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

相关文章

前端通信

Node中的net模块提供的前端通信 H5提供的 webSocket 【 常用于 移动端 】pc端低版本浏览器使用 socket.io 通信- 服务端&#xff1a; 总的服务器 举例&#xff1a; 腾讯的qq服务器 1个整体- 客户端&#xff1a; 单个用户使用应用 举例&#xff1a; 每个人的qq 多个client.js 客…

java定位线程阻塞_Arthas - 定位 Java 性能问题原来这么简单

目录&#xff1a;一、Arthas 介绍二、Arthas 使用场景三、Arthas怎么使用四、Arthas 定位性能问题定位Java代码导致占用CPU高的问题线程死锁前言&#xff1a;在做性能测试的过程中&#xff0c;当遇到Java性能问题&#xff0c;比如CPU飙升&#xff0c;负载突高&#xff0c;内存溢…

SVN 本地文件锁/服务端文件锁清除步骤

1.本地文件锁&#xff0c;直接cleanup&#xff0c;cleanup界面选择break locks即可 2.服务端文件锁&#xff0c;本地文件右击没有release lock或者break lock的选项时 方法1&#xff1a;右键&#xff0c;svn选择browser repo&#xff0c;找到该文件&#xff0c;右击&#xff0c…

java 对象复活_Java对象复活

java 对象复活总览 收集覆盖了finalize&#xff08;&#xff09;的对象之后&#xff0c;将其添加到终结处理队列中&#xff0c;以在调用每个对象的finalize&#xff08;&#xff09;方法之后进行清理。 如果您复活了物体&#xff0c;会发生什么&#xff1f; 何时定案&#xff…

a b和c 15 java_1011. A+B和C (15)

给定区间[-231, 231]内的3个整数A、B和C&#xff0c;请判断AB是否大于C。输入格式&#xff1a;输入第1行给出正整数T(<10)&#xff0c;是测试用例的个数。随后给出T组测试用例&#xff0c;每组占一行&#xff0c;顺序给出A、B和C。整数间以空格分隔。输出格式&#xff1a;对…

深入浅出《设计模式》之工厂模式(C++)

前言 模式介绍 在之前简单工厂模式中&#xff0c;我们介绍了简单工厂模式的缺陷是违背了开放-封闭原则。如果在面馆中添加了烤海参&#xff0c;那将会修改waiter工厂类。违背了类内封闭原则。 还以面馆为例&#xff0c;现在两种面&#xff0c;用一个服务员来卖就可以&#xff0…

当心Spring缓慢的事务回调

TL; DR 如果您的应用程序无法获得新的数据库连接&#xff0c;则重新启动ActiveMQ代理可能会有所帮助。 有兴趣吗 性能问题 几个月前&#xff0c;我们经历了生产中断。 大家都很熟悉&#xff0c;许多请求都失败了&#xff1a; java.sql.SQLTransientConnectionException: Hika…

jmeter学习笔记(八-1)

Jmeter中有较多需要参数化测试的地方&#xff1a; 1.从一个用户登录的接口获取登录后的token值&#xff0c;取值后用于后续接口调用 2.获取用户浏览后的cookies信息&#xff0c;需要用到HTTP Cookie 管理器来为同一线程组提供通用的cookies信息 Jmeter中通过${}形式来取参数值 …

python 对象转dict_如何将python dict对象转换为java等效对象?

总是有jython。这里有一点来自this article&#xff0c;它提供了python/java的良好并排视图The Jython analogues to Javascollection classes are much moretightly integrated into the corelanguage, allowing for more concisedescriptions and useful functionality.For e…

NOIP模拟测试5「星际旅行·砍树·超级树」

星际旅行 0分 瞬间爆炸。 考试的时候觉得这个题怎么这么难&#xff0c; 打个dp&#xff0c;可以被儿子贡献&#xff0c;可以被父亲贡献&#xff0c;还有自环&#xff0c;叶子节点连边可以贡献&#xff0c;非叶子也可以贡献&#xff0c;自环可以跑一回&#xff0c;自环可以跑两回…

学java选i5还是i7_选笔记本电脑,到底CPU是要选i5还是i7

又到了一年毕业季&#xff0c;准备上大学的学生们肯定是摩拳擦掌&#xff0c;准备入手一台新的笔记本电脑。而我们在选购笔记本电脑的时候&#xff0c;经常会遇到不同的配置&#xff0c;比如说同一台笔记本电脑会有i5以及i7两个处理器可供选择&#xff0c;而价格往往相差一两千…

apache apollo_Apache Apollo REST API

apache apolloApache Apollo是新一代&#xff0c;高性能&#xff0c;多协议的消息传递代理&#xff0c;它是从头开始构建的&#xff0c;可以替代ActiveMQ5.x。 我过去曾在博客上发表过文章 &#xff08;第一部分已经与第二部分一起发布了&#xff09;。 Apollo的无阻塞异步体系…

Node 之 模块加载原理与加载方式

Node.js中的模块可以分为原生模块和文件模块&#xff0c;通过Node.js中可以通过require方法导入模块、exports方法导出模块。 1、require导入模块 对于原生模块&#xff08;比如说&#xff1a;http&#xff09;&#xff0c;只需要使用require&#xff08;‘http’&#xff09;导…

php excel 下拉菜单,使用 PHPExcel 遇到的一个问题:下拉列表的数据来源过长时,显示了别的正常的下拉列表的数据来源...

遇到的问题&#xff1a;我们还是先来看手册是怎么说的&#xff1a;It is important to remember that any string participating in an Excel formula is allowed to be maximum 255 characters (not bytes).当下拉列表的数据来源过长(more than 255 characters)时&#xff0c;…

有效的Java –创建和销毁对象

创建和销毁对象&#xff08;第2章&#xff09; 这是Joshua Blochs的《 有效的Java》第2章的简短摘要。我仅包括与自己相关的项目。 静态工厂&#xff08;项目1&#xff09; 静态工厂与构造函数的一些优点&#xff1a; 工厂方法的名称为构造函数添加了描述 他们可以返回预先构…

【洛谷P2743】【poj 1743】[USACO5.1]乐曲主题Musical Themes

题目 还是板子题 因为旋律会同时加减一个数&#xff0c;所以我们在差分数组上做就好了 注意因为差分了&#xff0c;跨越的个数要少一个 基数排序循环写反了&#xff0c;调了好久 qwq /* Date : 2019-07-19 10:17:22 Author : Adscn (adscnqq.com) Link : https://www.cn…

exec导入 php,PHP exec运行一个文件

我正在尝试最后3个小时告诉PHP运行一个简单的文件.我在本地主机中使用wamp服务器用于Windows(Windows 8)我尝试过使用exec()&#xff1a;echo exec(whoami);我得到了权威的回应.还测试了&#xff1a;if(function_exists(exec)) {echo "exec is enabled";}它可能有用吗…

远程连接Oracle 数据库连接报错ORA-12638身份检索失败

数据库版本&#xff1a;oracle11g 当使用navicate或者PLsql使用远程连接服务器的数据库的时候报错 RA-12638身份检索失败 因为是更换了个新电脑出现这种问题了&#xff0c;所以可以排除时服务器数据库的问题&#xff0c;问题应该出现在oracle的客户端上面&#xff1b; 通过修改…

java生成顺丰电子面单,顺丰拼多多电子面单设置教程

100%使用使用拼多多电子面单&#xff0c;无需解密&#xff0c;即可打单发货&#xff0c;让打单更加流畅&#xff0c;减少出错&#xff01;不少商家有疑问&#xff0c;顺丰是月结的合作模式&#xff0c;不用充快递单号&#xff0c;是不是不支持拼多多电子面单呢&#xff1f;当然…

list.action.php,doAction.php里代码可以这样写,大大减少了重复的代码

//接收页面$mysqlinew Mysqli(localhost,root,root,test);if($mysqli->connect_errno){die(Connect Error:.$mysqli->connect_error);}$mysqli->set_charset(utf8);$username$_POST[username];$username$mysqli->escape_string($username);$password$_POST[passwor…