集合(一)Collection、List、ArrayList和Vector
一、Collection
集合存放在java.util包中,可以看作是集成好的数据结构,供你调用,十分方便,集合经常拿来和数组对比,其实我觉得没啥可比性,不过还是简单来看看它们的区别:
1.数组长度固定,而集合长度不固定。
2.集合只能存储对象,但数组不仅能存储基本类型还有对象数组。
3.集合存储的是对象的引用,对象本身不连续(待证实),而数组元素与元素内存连续。
4.一个数组只能存相同的数据类型,集合能存不同的数据类型。(补充例子)
先来张图,话说好像是第一次上图。。。


图1来源: http://www.cnblogs.com/taiwan/p/6954135.html
图2出处:http://www.cnblogs.com/skywang12345/p/io_07.html
这两个图展示了基本集合的关系,暂时也考虑按这个顺序来复习。Collection和Map是两个根接口,互不影响。
二、List
上篇也说到了List其实是一个接口,并且实现父接口Collection,实现它的类有ArrayList、Vector和LinkedList。
但基本上的使用方法都是:List l=new ArrayList(); List l=new Vector();
Collection和List的方法包括(均为JDK1.7的基本功能、例如Collection接口1.8版本新增4个功能 注:removeIf spliterator stream parallelStream,List接口新增3个功能 注:spliterator replaceAll sort):
abstract boolean add(E object)
abstract boolean addAll(Collection<? extends E> collection)
abstract void clear()
abstract boolean contains(Object object)
abstract boolean containsAll(Collection<?> collection)
abstract boolean equals(Object object)
abstract int hashCode() //equal和hashCode两个方法Object也有,Collection和List都是覆盖过的。
abstract boolean isEmpty() //注:Vector也有覆盖,但ArrayList和LinkedList没有。
abstract Iterator<E> iterator()
abstract boolean remove(Object object)
abstract boolean removeAll(Collection<?> collection)
abstract boolean retainAll(Collection<?> collection)
abstract int size()
abstract <T> T[] toArray(T[] array)
abstract Object[] toArray()
————————————————上面是Collection,下面是List————————————————
abstract void add(int location, E object)
abstract boolean addAll(int location, Collection<? extends E> collection)
abstract E get(int location)
abstract int indexOf(Object object)
abstract int lastIndexOf(Object object)
abstract ListIterator<E> listIterator(int location)
abstract ListIterator<E> listIterator()
abstract E remove(int location)
abstract E set(int location, E object)
abstract List<E> subList(int start, int end)
而对于实现List接口的主要三个数据结构分别是ArrayList、Vector、LinkedList,其中ArrayList和Vector是很类似的,都类似于可变长的对象数组,但是ArrayList不是线程安全的,而Vector是线程安全的,这个到学习线程部分再详说吧,暂时先理解为适合单线程和多线程。LinkedList则是链表(线程不安全,其实集合类中Vector、Stack、Hashtable和Enumeration是线程安全的,其余都是线程不安全的),适合增删操作较多时,那两个比较适合遍历操作,面向的任务不同。
1.对于ArrayList来说,新增的方法如下:
Object clone()
void ensureCapacity(int minimumCapacity)
void trimToSize()
void removeRange(int fromIndex, int toIndex) ArrayList是一个类,实现List接口,成员域有两个,分别为:
private int size; // 实际元素个数
transient Object[] elementData; //数组存放内容
构造函数有3个,无参构造函数,capacity=10,size=0(但其实其中过程较为复杂,ArrayList是在添加第一个元素时才实现了初始容量为10的构造,
可以参考https://blog.csdn.net/jdsjlzx/article/details/52675726和https://blog.csdn.net/m0_37884977/article/details/80514809);
以initialCapacity 参数的构造函数,capacity=initialCapacity size=0;以Collection为参数的构造函数,size=capacity=原Collection的size;
package list;
import java.lang.reflect.Field;
import java.util.ArrayList;
public class Capacity {
public static void main(String[] args) {
// ArrayList <Integer> al=new ArrayList<Integer>();
// ArrayList <Integer> al=new ArrayList<Integer>(4);
ArrayList <Integer> bl=new ArrayList<Integer>();
for(int i=0;i<9;i++)
{
bl.add(i);
}
ArrayList <Integer> al=new ArrayList<Integer>(bl);
System.out.println(al.size());
System.out.println(getArrayListCapacity(al));
al.add(1);
System.out.println(al.size());
System.out.println(getArrayListCapacity(al));
for(int i=0;i<9;i++)
{
al.add(i);
}
System.out.println(al.size());
System.out.println(getArrayListCapacity(al));
al.add(11);
System.out.println(al.size());
System.out.println(getArrayListCapacity(al));
for(int i=0;i<5;i++)
{
al.add(i);
}
System.out.println(al.size());
System.out.println(getArrayListCapacity(al));
}
public static int getArrayListCapacity(ArrayList<?> arrayList) {
Class<ArrayList> arrayListClass = ArrayList.class;
try {
Field field = arrayListClass.getDeclaredField("elementData");
field.setAccessible(true);
Object[] objects = (Object[])field.get(arrayList);
return objects.length;
} catch (NoSuchFieldException e) {
e.printStackTrace();
return -1;
} catch (IllegalAccessException e) {
e.printStackTrace();
return -1;
}
}
}
当容量不够时,ArrayList自动扩容到1.5倍的下取整10-15-22-33;4-6-9-13-19;这个样子
关于ArrayList的操作直接上代码:
/*ensureCapacity和trimToSize方法*/
al.ensureCapacity(38); //42 if parameter<1.5oldCapacity newCapacity=1.5Capacity else newCapacity=parameter
System.out.println(getArrayListCapacity(al));
al.ensureCapacity(43); // 63
System.out.println(getArrayListCapacity(al));
al.trimToSize(); //使capacity=size
System.out.println(al.size());
System.out.println(getArrayListCapacity(al));
package list; import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
//ArrayList Function
public class collection {
public static void main(String []args)
{
ArrayList <Integer> a=new ArrayList<Integer>();
ArrayList <Integer> b=new ArrayList<Integer>();
ArrayList <Integer> c=new ArrayList<Integer>();
/*四种Add操作*/
for(int i=0;i<10;i++)
{
c.add(i);
}
a.add(8);
a.addAll(c);
b.addAll(0, c);
b.add(5,55); //插入在index前面一位 /*contains操作*/
System.out.println(b.contains(0)); //true
System.out.println(b.contains(null)); //false
// Object p=new Object();
// System.out.println(p.equals(null)); 永远false /*Iterator*/
Iterator <Integer> it=b.iterator();
while(it.hasNext())
{
System.out.print(it.next()+" ");
}
System.out.println(); /*retainAll*/
b.retainAll(a); //只要b中元素不在a中(即a中没有),就删掉。 /*ListIterator<E> listIterator(int index)
* 从下标index开始为第一个,而且可以向前previous()和hasPrevious()*/
ListIterator <Integer> it1=b.listIterator(0);
while(it1.hasNext())
{
System.out.print(it1.next()+" ");
}
System.out.println(); /*subList 形成一个视图*两者联动一个变,另一个也变/
List<Integer> d=b.subList(2, 7);
d.set(0, 888); /*ForEach*/
for(int j:d)
{
System.out.print(j+" ");
}
System.out.println();
for(int j:b)
{
System.out.print(j+" ");
}
System.out.println();
d.remove(3);
for(int j:d)
{
System.out.print(j+" ");
}
System.out.println();
for(int j:b)
{
System.out.print(j+" ");
}
System.out.println();
d.set(3,333);
for(int j:d)
{
System.out.print(j+" ");
}
System.out.println();
for(int j:b)
{
System.out.print(j+" ");
}
System.out.println();
/**/ } }
结果:
true
false
0 1 2 3 4 55 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
888 3 4 5 6
0 1 888 3 4 5 6 7 8 9 //d变b也变
888 3 4 6
0 1 888 3 4 6 7 8 9
888 333 4 6
0 1 888 333 4 6 7 8 9 //b变d也变
其他操作:
深层拷贝和浅层拷贝:深层拷贝是指完全复制,不指向同一元素;浅层拷贝指向同一元素
而ArrayList的clone()方法是一种浅层拷贝方法?(不知如何验证,所以也不确定)
package list;
import java.util.ArrayList;
public class arraylist {
public static void main(String[] args) {
// ArrayList <Integer> a=new ArrayList<Integer>(); //互不影响
ArrayList <String> a=new ArrayList<String>();
for(int i=0;i<9;i++)
{
a.add(String.valueOf(i)+"aa");
}
ArrayList <String> b=(ArrayList<String>) a.clone(); //cast
for(String j:a)
{
System.out.print(j+" ");
}
System.out.println();
for(String j:b)
{
System.out.print(j+" ");
}
System.out.println();
a.remove(0);
for(String j:a)
{
System.out.print(j+" ");
}
System.out.println();
for(String j:b)
{
System.out.print(j+" ");
}
System.out.println();
b.remove(1);
for(String j:a)
{
System.out.print(j+" ");
}
System.out.println();
for(String j:b)
{
System.out.print(j+" ");
}
System.out.println();
}
}
总是互相不关联,看起来像是深度复制啊?还是实验设计有问题?
2.Vector
Vector有3个成员域:
int elementCount; // 实际元素个数
Object[] elementData; //动态数组存放内容
int capacityIncrement //
四个构造函数:
默认构造函数:Vector(); capacity=10,increment=0
单参数构造函数:Vector(int initCapacity); capacity=initCapacity,increment=0
双参数构造函数:Vector(int initCapacity,int capacityIncrement); capacity=initCapacity,increment=capacityIncrement
Collection构造函数:Vector(Collection c)
向量的大小大于其容量时,容量自动增加的量。如果在创建Vector时,指定了capacityIncrement的大小;则,每次当Vector中动态数组容量增加时,增加的大小都是capacityIncrement。如果容量的增量小于等于零,则每次需要增大容量时,向量的容量将增大一倍。若是ensureCapacity(int minCapacity)方法,首先判断capacityIncrement是否大于0,若大于0新容量newCapacity=oldCapacity+capacityIncrement。否则newCapacity=oldCapacity*2。之后选择newCapacity和minCapacity较大的那一个当作新的容量。ensureCapacirt(int minCapacity)核心代码:
private void grow(int minCapacity) {
int oldCapacity = elementData.length; //旧容量
int newCapacity = oldCapacity + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity); //capacity>0直接加,小于等于0翻倍
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity; //之后判断是否大于参数,选较大的
if (newCapacity - MAX_ARRAY_SIZE > 0)//
newCapacity = hugeCapacity(minCapacity);
elementData = Arrays.copyOf(elementData, newCapacity);
}
public synchronized void ensureCapacity(int minCapacity) {
if (minCapacity > 0) {
modCount++;//
ensureCapacityHelper(minCapacity);
}
private static int hugeCapacity(int minCapacity) {
if (minCapacity < 0) // overflow
throw new OutOfMemoryError();
return (minCapacity > MAX_ARRAY_SIZE) ?
Integer.MAX_VALUE :
MAX_ARRAY_SIZE;
}
原文:https://blog.csdn.net/zhangveni/article/details/51000873
Vector中的API:
synchronized boolean add(E object) //尾部增加元素@@@@
void add(int location, E object) //下标location之前插入元素@@@@
synchronized boolean addAll(Collection<? extends E> collection) //@@@@
synchronized boolean addAll(int location, Collection<? extends E> collection) //@@@@
synchronized void addElement(E object) //除返回值不同,其他和add一样
synchronized int capacity()
void clear() //@@@@
synchronized Object clone() ####
boolean contains(Object object) //@@@@
synchronized boolean containsAll(Collection<?> collection) //@@@@
synchronized void copyInto(Object[] elements) //***********//
synchronized E elementAt(int location)
Enumeration<E> elements() //***********//
synchronized void ensureCapacity(int minimumCapacity) #####
synchronized boolean equals(Object object) //@@@@
synchronized E firstElement()
E get(int location) //@@@@
synchronized int hashCode() //@@@@
synchronized int indexOf(Object object, int location) //***********//
int indexOf(Object object) //@@@@
synchronized void insertElementAt(E object, int location)
synchronized boolean isEmpty() //@@@@
synchronized E lastElement()
synchronized int lastIndexOf(Object object, int location)
synchronized int lastIndexOf(Object object) @@@@
synchronized E remove(int location) @@@@
boolean remove(Object object) @@@@
synchronized boolean removeAll(Collection<?> collection) @@@@
synchronized void removeAllElements()
synchronized boolean removeElement(Object object)
synchronized void removeElementAt(int location)
synchronized boolean retainAll(Collection<?> collection) @@@@
synchronized E set(int location, E object) @@@@
synchronized void setElementAt(E object, int location)
synchronized void setSize(int length) //************//
synchronized int size() @@@@
synchronized List<E> subList(int start, int end) @@@@
synchronized <T> T[] toArray(T[] contents) @@@@
synchronized Object[] toArray() @@@@
synchronized String toString() //******
synchronized void trimToSize() ####
add和addElement几乎一致,还有set和setElementAt、insertElementAt和add双参数、get和ElementAt、remove和removeElement [2]以及removeAllElement和clear。这几乎都是因为从List继承一些方法,然后本身又会自带一些,有些返回值不同,但实现的功能没有大差。上述列表中,带@是继承自List和Collection的方法,带#是和Arraylist一样方法(ensureCapacity其实也不一样)。剩下的好像只有Element那些重复的和为数不多的方法了。
因此主要实现上述带有标志 * 的及其相关的方法为示例:
package vector; import java.util.Enumeration;
import java.util.Iterator;
import java.util.Vector; public class vector {
public static void main(String[] args) {
// TODO Auto-generated method stub
Vector <String> vs=new Vector<String>();
String [] st=new String[20];
String [] st2=new String[20];
/*add*/
for(int i=0;i<10;i++)
{
vs.add(String.valueOf(i));
}
/*capacity*/
System.out.println(vs.capacity());
vs.add(5, "5");
vs.addElement("am ");
System.out.println(vs.capacity());
/*iterator*/
Iterator<String> it=vs.iterator();
while(it.hasNext())
{ System.out.print(it.next()+" ");
}
System.out.println();
/*indexOf lastIndexOf*/
System.out.print(vs.indexOf("5")+" "); //第一个出现该元素的下标
System.out.print(vs.lastIndexOf("5")+" "); //最后一个出现该元素的下标
System.out.print(vs.lastIndexOf("10")+" "); //没有的元素返回-1
System.out.print(vs.indexOf("8",9)+" "); //返回的元素必须大于等于第二个参数
System.out.print(vs.lastIndexOf("5",5)+" "); //返回的参数小于等于第二个参数,否则返回-1
System.out.println();
/*setsize*/
vs.setSize(20); //若小于当前size,删除后面元素,若大于添加null
/*enum*/
Enumeration<String> en=vs.elements();
while(en.hasMoreElements())
{ System.out.print(en.nextElement()+' ');
}
System.out.println(); /*copyInto*/
vs.copyInto(st);
for(String a:st)
{
System.out.print(a+" ");
}
System.out.println();
/*toString*/
System.out.println(vs.toString());
}
}
20
0 1 2 3 4 5 5 6 7 8 9 am
5 6 -1 9 5
0 1 2 3 4 5 5 6 7 8 9 am null null null null null null null null
0 1 2 3 4 5 5 6 7 8 9 am null null null null null null null null
[0, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9, am , null, null, null, null, null, null, null, null]
太多了LinkedList移到下一篇吧。
集合(一)Collection、List、ArrayList和Vector的更多相关文章
- java集合框架collection(2)ArrayList和LinkedList
ArrayList是基于动态数组实现的list,而LinkedList是基于链表实现的list.所以,ArrayList拥有着数组的特性,LinkedList拥有着链表的特性. 优缺点 ArrayLi ...
- Java集合框架Collection(1)ArrayList的三种遍历方法
ArrayList是java最重要的数据结构之一,日常工作中经常用到的就是ArrayList的遍历,经过总结,发现大致有三种,上代码: package com.company; import java ...
- Java进阶(四十六)简述ArrayList、Vector与LinkedList的异同点
简述ArrayList.Vector与LinkedList的异同点 Collection类的继承图如下: 从图中可以看出,LinkedList与ArrayList.ArrayDeque这三者都 ...
- 集合中list、ArrayList、LinkedList、Vector的区别、Collection接口的共性方法以及数据结构的总结
List (链表|线性表) 特点: 接口,可存放重复元素,元素存取是有序的,允许在指定位置插入元素,并通过索引来访问元素 1.创建一个用指定可视行数初始化的新滚动列表.默认情况下,不允许进行多项选择. ...
- Java——(五)Collection之List集合、ArrayList和Vector实现类
------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.List集合 List集合代表一个元素有序.客重复的集合,集合中每个元素都有其对应的顺序索引 ...
- 集合框架,ArrayList和Vector的区别,让arrayList线程安全的几种方案
boolean add(E e) 将指定的元素添加到此列表的尾部. void add(int index, E element) 将指定的元素插入此列表中的指定位置. boolean addAll(C ...
- 16、Collection接口及其子接口Set和List(常用类LinkedList,ArrayList,Vector和Stack)
16.Collection接口 Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements).一些Collection允许相同 ...
- Java基础---集合框架---迭代器、ListIterator、Vector中枚举、LinkedList、ArrayList、HashSet、TreeSet、二叉树、Comparator
为什么出现集合类? 面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式. 数组和集合类同是容器,有何不同? 数组虽然也可以存储对 ...
- 09 Collection,Iterator,List,listIterator,Vector,ArrayList,LinkedList,泛型,增强for,可变参数,HashSet,LinkedHashSet,TreeSet
09 Collection,Iterator,List,listIterator,Vector,ArrayList,LinkedList,泛型,增强for,可变参数,HashSet,LinkedHas ...
随机推荐
- jdk1.8-ArrayList源码分析
一:idea可以自动生成UML类图,ctrl+alt+u ArrayList类图 我没们看下类的继承关系 ) { ) { ) { )) )) newCapacity = minCapacity) ne ...
- 车载导航应用中基于Sketch UI主题实现
1.导读 关于应用的主题定制,相信大家或多或少都有接触,基本上,实现思路可以分为两类: 内置主题(应用内自定义style) 外部加载方式(资源apk形式.压缩资源.插件等) 其实,针对不同的主题定制实 ...
- vue-cli 3.x 构建项目,webpack没有了?
vue-cli 3.x 已经没有了webpack.config.js文件.取而代之的是创建一个vue.config.js文件.官网是这样介绍的 vue.config.js const path = r ...
- 数据中心网络中的40GBASE-T
数据中心网络基础设施正在见证由不断增长的带宽和网络性能需求推动的变革.10 千兆位以太网是当今数据中心的实际标准,而 40G 以太网的采用率越来越高.虽然 40G 以太网标准已存在于 SM 光纤和基于 ...
- C#编程 socket编程之unity聊天室
上面我们创建了tcp的客户端和服务端,但是只能进行消息的一次收发.这次我们做一个unity的简易聊天室,使用了线程,可以使用多个客户端连接服务器,并且一个客户端给服务器发消息后,服务器会将消息群发给所 ...
- yum安装telnet如何开启telnet服务
1.# yum install -y telnet telnet-server xinetd (其中telnet-server是由xinetd管理的,所以得下载xinetd服务) 2.修 ...
- hbase的hue部署和使用
1.组件版本信息 zookeeper hadoop hbase hue zookeeper-3.4.12 hadoop-3.0.3 hbase-2.1.5 4.4.0 2. ...
- [Python3] 035 函数式编程 高阶函数
目录 函数式编程 之 高阶函数 1. 引子 2. 系统提供的高阶函数 3. functools 包提供的 reduce 4. 排序 函数式编程 之 高阶函数 把函数作为参数使用的函数,叫高阶函数 1. ...
- try catch和finally
在C#中这三个关键字用于处理异常. 这三个关键字try是必定要用的,要不然就失去了意义.然后catch和finally可以不用但是要注意遵循原则. 存在一个或多个catch的时可以不用finally, ...
- C# 如何判断指定文件是否正被其它程序使用
C# 如何判断指定文件是否正被其它程序使用 起因:项目中发现在操作文件时,系统经常抛出异常,表示文件正被其它程序占用. 需求:为了事先判断,以确认指定的文件是否正被其它程序使用,需要方法进行判断. 思 ...