Java中的集合框架-Collection(一)
一,Collection接口
在日常的开发工作中,我们经常使用数组,但是数组是有很多的局限性的,比如:数组大小固定后不可修改,只能存储基本类型的值等等。
基于数组的这些局限性,Java框架就产生了用于解决此类问题的工具,即集合框架。
Java中有许多的集合框架类,基于这些类的共性特征,向上高度抽取,便形成了共性的集合框架接口-Collection。
由于此接口属于工具性质的,所以它属于util包,java核心的内容在lang核心包里存放着。
由于Collection是抽取了各集合的共性所形成的接口,所以所有的集合类都实现了此接口,此接口的特点如下:
1,它是用于存储对象的容器
2,可动态扩展容量
3,不能存储基本类型的值
我们在开发中对数组或集合的操作无非是增删改查四种操作,当然Collection接口既然是对各种集合的高度抽取的操作,它里面的方法也无非这四种。下面对这四种方法进行分类总结
1,添加
add 将指定的某一个元素添加到集合中
addAll 将指定的集合对象一次性添加到集合中
2,修改
对集合的修改无非是获取集合中的某一个元素然后再重新赋给新值
3,查询(获取)
iterator 此方法返回一个迭代器对象,方便用于对集合中的每个元素进行循环获取操作
contains 是否包含某个元素
containsAll 是否包含另一个集合中的所有元素
equals 比较两个集合是否相等
isEmpty 判断一个集合是否为空
size 获取集合中元素的数量
retainAll 求和另外一个集合的交集
4,删除
remove 删除集合中的某一个元素
removeAll 删除集合中某一个子集(参数为集合对象)
clear 清除集合中所有的元素
5,其它
toArray 返回包含此集合元素的数组对象
hashcode 返回此集合元素的哈希码
以上是Collection接口的所有的方法,由于具体操作都由它的实现类来完成,并且都比较简单,所以演示代码在介绍他们的实现类的时候再列出。
Collection接口有着许多的实现类及子接口,这些实现类或子接口中,一些是允许重复的,另外一些不允许重复;一些是有序的,而另外一些则是无序的。日常开发中比较常用的大致分为两类:List与Set(其实用了是这两个接口的实现类),下面用类图的方式从顶层往底层一层一层的添加Collection接口的子接口或实现类来把集合框架说完
二,List接口
1,List接口是有序的,这个有序是指存储的到集合中的元素的顺序与取出的顺序是一致的;
private static void function_demo2() {
List list = new ArrayList();
list.add(0);
list.add(2);
list.add(3);
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
这段程序的运行结果:
与添加元素的顺序是一致的
2,List接口里的元素允许重复;同样是上面的程序,我们再添加一个元素
list.add(3);
程序的运行结果如下:
3,List接口里的元素允许有null值;还是上面的程序,我们添加一个null元素
list.add(null);
程序运行结果如下:
4,允许像数组一样用索引进行元素位置的操作;索引的位置从0开始,和数组相类似
5,List常用方法演示
private static void function_demo1() {
List list = new ArrayList();
list.add("张三");// 将元素添加到列表的尾部
list.add(0, "李四");// 将元素添加到列表的指定位置
List list2 = new ArrayList();
list2.add("王五");
list2.add("赵六");
list.addAll(list2);// 将一个集合中的元素添加到另一个集合中尾部
list.addAll(0, list2);// 将一个集合中的元素添加到另一个集合中指定位置
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));// get方法获取指定位置的元素
}
list.contains("张三");// 集合是否存储了某一个元素,若存储了该元素则返回true
list.containsAll(list2);// 集合是否包含了另外一个集合的所有元素,若包含了,则返回true
list.indexOf("张三");// 集合是查询到第一次出现“张三”的索引位置,若集合中没有“张三”则返回-1
list.lastIndexOf("张三");// 集合中最后一次出现“张三”的索引位置,若没有“张三”则返回-1
list.isEmpty();// 集合是否没有任何元素,若是空集合则返回true
list.remove("张三");// 移除第一次出现的“张三”
list.remove(0);// 移除指定位置上的元素
list.removeAll(list2);// 移除所包含的集合元素(差集)
list.retainAll(list2);// 两个集合的并集
list.set(0, "马六");// 设置指定位置的值
list.size();// 集合的元素个数
list.subList(2, 4);// 返回list的子集,包括位置2但不包括4
Object[] obj = list.toArray();// 返回集合中所有的元素组成的数组
String[] ary = new String[list.size()];
list.toArray(ary);// 返回集合中所有的元素组成的数组,但是可以指定其返回的数组数据类型,即此方法的参数数组类型
list.clear();// 移除集合中所有的元素
}
注:以上代码中用for循环取出集合中的元素方法是List集合所物有的方式
6,List里的iterator和listIterator方法
我们知道,用iterator方法可以获取一个迭代器对象,然后方便对集合中的元素进行循环的访问,现在有一个这样的需求,循环遍历集合中的元素,当元素为“张三”时,为集合添加一个元素,实现代码如下
private static void function_demo3() {
List list = new ArrayList();
list.add("张三");// 将元素添加到列表的尾部
list.add(0, "李四");// 将元素添加到列表的指定位置
List list2 = new ArrayList();
list2.add("王五");
list2.add("赵六");
list.addAll(list2);// 将一个集合中的元素添加到另一个集合中尾部
list.addAll(0, list2);// 将一个集合中的元素添加到另一个集合中指定位置
Iterator it = list.iterator();//获取迭代器对象
while (it.hasNext()) {
String str = it.next().toString();
if (str.equals("张三")) {
list.add("马七");
} else {
System.out.println(str);
}
}
}
程序运行结果:
经调试发现,程序在运行到“张三”这个元素后为集合添加元素时,抛出了java.util.ConcurrentModificationException异常,此异常是当方法检测到对象的并发修改,但不允许这种修改时,抛出此异常。我们可以得出结果,就是iterator接口不允许我们在读取的时候进行修改操作。
而listIterator方法返回一个ListIterator接口,此接口允许在进行迭代的时候进行添加删除修改的操作,并可按任一方向(前或后)进行遍历操作,演示代码如下
private static void function_demo3() {
List list = new ArrayList();
list.add("张三");// 将元素添加到列表的尾部
list.add(0, "李四");// 将元素添加到列表的指定位置
List list2 = new ArrayList();
list2.add("王五");
list2.add("赵六");
list.addAll(list2);// 将一个集合中的元素添加到另一个集合中尾部
list.addAll(0, list2);// 将一个集合中的元素添加到另一个集合中指定位置
ListIterator it = list.listIterator();// 获取迭代器对象
while (it.hasNext()) {
String str = it.next().toString();
if (str.equals("张三")) {
System.out.println(str);
it.add("马七");//此处用的是ListIterator的对象it即调用的是ListIterator的方法进行添加操作
} else {
System.out.println(str);
}
}
System.out.println(list.size());
}
使用listIterator不但可以在迭代的同时进行增删改的操作,还可以回退着读即调用hasPrevious方法,此处不再演示
注:此功能仅有List集合具备
1,List常用实现类Vector
Vector类是个比较古老的类,从1.0版本便有了,也就是说此类是先于集合框架出现的,只是由于效率问题到后来并到List下面的。
Vector类内部维护的是一个数组,此数组可动态扩展。若实例化该类时用的是无参构造则数组默认大小为10,当此容器内部的数量大于10时,容量则动态扩展一倍;也可在实例化该类时指定初始大小,并可指定增长量;演示如下:
private static void function_demo4() {
Vector v = new Vector();// 使用默认大小
System.out.println("Vector默认容量:" + v.capacity());
Vector v2 = new Vector(2);// 指定初始大小为2
System.out.println("Vector默认容量:" + v2.capacity());
v2.add(2);
v2.add(3);
System.out.println("元素个数:" + v2.size());
System.out.println("Vector默认容量:" + v2.capacity());
v.add(3);
System.out.println("元素个数:" + v2.size());
System.out.println("Vector默认容量:" + v2.capacity());//此时元素个数超出来初始大小2,便动态扩展一倍的容量
}
指定容量大小,并指定增长量大小演示如下:
private static void function_demo5() {
Vector v = new Vector(2, 1);// 默认大小为2,当超出后每次增长1
v.add(2);
v.add(3);
System.out.println("元素个数:" + v.size());
System.out.println("Vector默认容量:" + v.capacity());
v.add(4);
System.out.println("元素个数:" + v.size());
System.out.println("Vector默认容量:" + v.capacity());
}
Vector除了实现了List接口后重写了List里的方法,还维护着它自己之前的方法,这些方法不但名字较长而且效率低下,完成的功能与List里的方法功能相同,如addElement方法和add方法,elementAt与indexOf方法等等,其中有一个方法用于遍历容器中的元素elements返回一个枚举器对象Enumeration被iterator所替代。
2,List常用实现类LinkedList
LinkedList是List接口的链表列表体现,即它的内部是链表的数据结构,所以它增删时的速度比较快,另外此类是非线程安全的,即非同步。
LinkedList除了实现了List接口的方法外,还提供了一些方法,这些方法可模拟堆栈,队列,和双端队列的操作。
基本的增删改查的方法就不再演示了,我们用LinkedList所提供的可模拟堆栈,队列和双端队列的方法来完成一个自定义的堆栈及队列操作。
我们知道,堆栈有一个特点即后进先出而队列的特点是先进先出,基于此可有以下操作:
public class DuiZhan {
private LinkedList linkedList; public DuiZhan() {
linkedList = new LinkedList();
} public void add(Object e) {
linkedList.push(e);
} public Object get() {
return linkedList.pollLast();
} }
public class DuiLie {
private LinkedList linkedList; public DuiLie() {
linkedList = new LinkedList();
} public void add(Object obj) {
linkedList.push(obj);
} public Object get() {
return linkedList.pollFirst();
}
}
3,List常用实现类ArrayList
ArrayList类是开发中最常用的类,此类内部是数组的形式;功能上基本与Vector相类似,但它是不同步的,是Vector的替代品;由于内部是数组结构,所以用于查询速度相对较快。
ArrayList低层所维护的数组的长度动态扩展大约每次扩展原来容量1.5倍的容量,但是ArrayList有一个方法ensureCapacity,此方法接收一个int类型的参数,这个方法的作用是当此方法所传递的参数为大于ArrayList默认容量的1.5倍时,ArrayList扩展为此参数大小的容量;如果此方法所传递的参数为小于ArrayList默认容量的1.5倍时,ArrayList扩展为默认值的1.5倍容量;这个容量的扩展与否关系着ArrayList执行效率的快慢问题,因为ArrayList扩容是新建一个数组,然后把原来数组中的内容复制到新数组中去,是很消耗资源的。下面用一个例子作以演示:
private static void function_demo8() {
int n = 100000;
ArrayList al = new ArrayList();
long startTime = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
al.add(i);
}
System.out.print("默认扩展容量耗时:");
System.out.println(System.currentTimeMillis() - startTime);
ArrayList al1 = new ArrayList();
al1.ensureCapacity(n);
startTime = System.currentTimeMillis();
for (int i = 0; i < n; i++) {
al1.add(i);
}
System.out.print("手动扩展容量耗时:");
System.out.println(System.currentTimeMillis() - startTime);
}
程序运行结果:
可以感受一下,这个差距还是很大的。另外ArrayList还有一个方法trimToSize,这个方法的作用是将容器的大小调整为与元素数量相同的大小,举例说明一下:假设ArrayList默认容量为10,当添加第11个元素的时候容量会扩展成15,但此时元素只有11个,另外的四个位置其实是浪费的,那么这个时候调用一下trimToSize方法会将多余的那四个位置给清除掉,具体不再演示,需要去扒源码。ArrayList的其它方法基本上没有什么难理解的了,就不再一一演示。
Java中的集合框架-Collection(一)的更多相关文章
- Java中的集合框架-Collection(二)
上一篇<Java中的集合框架-Collection(一)>把Java集合框架中的Collection与List及其常用实现类的功能大致记录了一下,本篇接着记录Collection的另一个子 ...
- 菜鸟日记之 java中的集合框架
java中的集合框架图 如图所示:java中的集合分为两种Collection和Map两种接口 可分为Collection是单列集合和Map的双列集合 Collection单列集合:继承了Iterat ...
- Java中的集合框架(上)
Java中的集合框架概述 集合的概念: Java中的集合类:是一种工具类,就像是容器,存储任意数量的具有共同属性的对象. 集合的作用: 1.在类的内部,对数据进行组织: 2.简单的快速的搜索大数据量的 ...
- Java中的集合框架-Collections和Arrays
上一篇<Java中的集合框架-Map>把集合框架中的键值对容器Map中常用的知识记录了一下,本节记录一下集合框架的两个工具类Collections和Arrays 一,Collections ...
- Java中的集合框架-Map
前两篇<Java中的集合框架-Commection(一)>和<Java中的集合框架-Commection(二)>把集合框架中的Collection开发常用知识点作了一下记录,从 ...
- Java学习--java中的集合框架、Collection接口、list接口
与数组相比:1.数组的长度固定,而集合的长度可变2.数组只能通过下表访问元素,类型固定,而有的集合可以通过任意类型查找所映射的具体对象 java集合框架:collection(list序列,queue ...
- Java中的集合框架
概念与作用 集合概念 现实生活中:很多事物凑在一起 数学中的集合:具有共同属性的事物的总体 java中的集合类:是一种工具类,就像是容器,储存任意数量的具有共同属性的对象 在编程时,常常需要集中存放多 ...
- Java中的集合框架(下)
学生选课--判断Set中课程是否存在 package com.imooc.collection; import java.util.ArrayList; import java.util.Arrays ...
- JAVA 中的集合框架
java集合框架提供了一套性能优良.使用方便的接口和类,它们位于java.util包中 一.集合与数组 数组:(可以存储基本数据类型)是用来存现对象的一种容器,但是数组的长度固定,不适合在对象数量未知 ...
随机推荐
- Android 二次打包(封装)AAR实用指南
前言 上次文章Android SDK开发与使用的那些事儿说到如何在aar里集成导入的aar,也就是二次封装aar的问题,一带而过,难免不过瘾.在封装这条路上也遇到了不少坑,现在将此方法详细记录下来. ...
- SSM 框架-02-MyEclipse 2017 安装与破解
SSM 框架-02-MyEclipse 2017 安装与破解 现在在学J2EE,然后使用的工具就是 MyEclipse,现在就抛弃 Eclipse 了,我就不多说它俩的区别了,但是 MyEclipse ...
- Monkey测试运用实例
测试命令是多样性的,根据个人的测试思路,设计执行你想要的测试命令 1.monkey -p com.junte -v 1000 团贷网模拟用户随机操作,无延时点击1000次 -p测试包 ...
- SQL点点滴滴_公用表表达式(CTE)递归的生成帮助数据
本文的作者辛苦了,版权问题特声明本文出处:http://www.cnblogs.com/wy123/p/5960825.html 工作有时候会需要一些帮助数据,必须需要连续的数字,连续间隔的时间点,连 ...
- Linux下调节CPU使用的几种方法
一,使用taskset充分利用多核cpu,让cpu的使用率均衡到每个cpu上 #taskset-p, 设定一个已存在的pid,而不是重新开启一个新任务-c, 指定一个处理,可以指定多个,以 ...
- java获取中文拼音首字母
import net.sourceforge.pinyin4j.PinyinHelper; public class PinyinHelperUtil { /** * 得到中文首字母(中国 -> ...
- 解决python3 UnicodeDecodeError: 'gbk' codec can't decode byte
本来想写个html来玩玩,结果读取文件得时候就BUG了.... 以下代码读取html中无中文没有问题. def handle_request(client): buf = client.recv(10 ...
- ZT android -- 蓝牙 bluetooth (四)OPP文件传输
android -- 蓝牙 bluetooth (四)OPP文件传输 分类: Android的原生应用分析 2013-06-22 21:51 2599人阅读 评论(19) 收藏 举报 4.2源码AND ...
- [T-ARA][넘버나인][No.9]
歌词来源: 넘버나인 (No.9):http://music.163.com/#/song?id=27808770 넘버나인(Club ver.):http://music.163.com/#/son ...
- scala当中的对象
1.scala当中的Object 在scala当中,没有类似于像java当中的static修饰的静态属性或者静态方法或者静态代码块之类的,但是我们可以通过scala当中的Object来实现类似的功能. ...