Java容器类类库的用途是“保存对象”,其有两个大类:
1)Collection。一个独立元素的序列,这些元素都服从一条或多条规则。Collection的三个子类(说是子类其实也是接口额),List,必须按照插入的顺序保存元素;Set不能有重复元素;Queue按照排队规则来确定对象昌盛的顺序。
2)Map。一组成对的“键值对”对象,允许你使用键来查找值。
一、Collection
Collection接口概括了序列的概念——一种存放一组对象的方式。
Collection主要方法:
boolean add(Object o)//添加对象到集合
boolean remove(Object o)//删除指定的对象
int size()//返回当前集合中元素的数量
boolean contains(Object o)//查找集合中是否有指定的对象
boolean isEmpty()//判断集合是否为空
Iterator iterator()//返回一个迭代器
boolean containsAll(Collection c)//查找集合中是否有集合c中的元素
boolean addAll(Collection c)//将集合c中所有的元素添加给该集合
void clear()//删除集合中所有元素
void removeAll(Collection c)//从集合中删除c集合中也有的元素
void retainAll(Collection c)//从集合中删除集合c中不包含的元素
二、List
List可以将元素维护在特定序列中,List接口在Collection的基础上添加了大量的方法,使得可以在List的中间插入和移除元素。
一般来说,我们常用的两种类型的List:
1、基本的ArrayList,它常用于随机访问元素,但是在ArrayList中间插入和移除元素时比较慢,下面看看ArrayList的使用
import java.util.ArrayList;
import java.util.List;
public class ArrayList_Test {
public static void main(String[]args)
{
//构造函数 ArrayList<E>(int initialCapacity) initialCapacity为ArrayList的大小,默认的容量为10
// E为存放的对象的类型(注:不能为基本类型,如,int,float;如果要使用的话可以使用Integer等封装类)
ArrayList<Integer> arrayList = new ArrayList<Integer>(10);
//插入 1)boolean add(E e) 2)void add(int index, E e) 第二种方法是把对象e插入到index的位置
System.out.println("插入数据:");
for(int i = 0; i < 9; i++)
{
arrayList.add(i);
}
arrayList.add(0, 9);
//这里超过了arralist的容量,但是它会自动的扩容,所以数据并没有丢失
arrayList.add(0, 10);
for(int i = 0; i < 11; i++)
{
//根据下标(index)我们可以利用E get(int index)方法得到这个地方存储的对象
System.out.print(arrayList.get(i) + " ");
}
System.out.println();
//当我们知道某个对象的时候想知道它在arraylist的哪个地方就可以使用int indexOf(Object o)方法
System.out.println("获取0的index:");
System.out.println(arrayList.indexOf(0));
//删除数据有两种方式 (1)boolean remove(Object o) (2)E remove(int index)
// 前者是通过对象来确定删除对象,后者是通过索引来确定
System.out.println("删除数据:0、2");
Integer integer = new Integer(2);
arrayList.remove(integer);
arrayList.remove(2);
//判断是否含有某个对象 boolean contains(Object o)(2)boolean containsAll(Collection<?> c)
System.out.println("检查一下2是否已经被删除:");
if(arrayList.contains(integer))
{
System.out.println("true");
}
else
{
System.out.println("false");
}
//值得一提的是,由于我们删除了两个元素,导致arraylist的大小发生了改变,直接copy上段的打印代码会报错
// 所以我们索性把长度改为arraylist.size()这样不管怎么改也不会报错了
System.out.println("此时的arrayl为:");
for(int i = 0; i < arrayList.size(); i++)
{
System.out.print(arrayList.get(i) + " ");
}
System.out.println();
//截取一段数据 List<E> subList(int fromIndex, int toIndex) (注意这里返回的是List类型)
System.out.println("截取1-6的数据");
List<Integer> list = arrayList.subList(1,6);
for(int i = 0; i < list.size(); i++)
{
System.out.print(list.get(i) + " ");
}
System.out.println();
//判断是否包含某个集合 boolean containsAll(Collection<?> c)
System.out.println("arraylist是否包含list");
if(arrayList.containsAll(list))
{
System.out.println("包含");
}
else
{
System.out.println("不包含");
}
//更改某个位置的对象 E set(int index, E element)这个方法将返回原index位置的对象
System.out.println("把第二个数(index=1)更换成0");
System.out.println(arrayList.set(1,0));
System.out.println("更换后list为:");
for(int i = 0; i < list.size(); i++)
{
System.out.print(list.get(i) + " ");
}
System.out.println();
//这里我们发现list中的9也变成了0,这是因为list的add方法并没有new一个新的对象,sublist也没有,所以指向的是同一个对象
//想要它不变就new一个list,在list的构造函数中会调用copyOf,会产生这个list的复制,而不是直接=
System.out.println("更换后arraylist为:");
for(int i = 0; i < arrayList.size(); i++)
{
System.out.print(arrayList.get(i) + " ");
}
System.out.println();
//移除这个arraylist中在另一个collection存在的元素,也就是arraylist-collection
//这里我们就可以使用boolean removeAll(Collection<?> c)
//而移除不存在于collection中的元素则使用boolean retainAll(Collection<?> c)
//直接清空arraylist使用void clear()
System.out.println("移除arraylist中存在于list中的元素");
arrayList.removeAll(list);
for(int i = 0; i < arrayList.size(); i++)
{
System.out.print(arrayList.get(i) + " ");
}
System.out.println();
}
}
2、LinkedList,其在中间进行插入和删除操作较快,但是随机访问比较慢
import java.util.LinkedList;
public class LinkedList_Test {
public static void main(String[]args)
{
//LinkedList和ArrayList的方法有很多是相同的,这里就只列出一些多的方法
//LinkedList为了能实现栈、队列以及双端队列新增的这些方法
LinkedList<Integer> linkedList = new LinkedList<Integer>();
for(int i = 0; i < 10; i++)
{
linkedList.add(i);
}
System.out.println("linkedlist:");
for(int i = 0; i < linkedList.size(); i++)
{
System.out.print(linkedList.get(i) + " ");
}
System.out.println();
//首先是返回列表的第一个对象而且不移除它
//有三种方法getFirst()、element()、peek() 前两种在LinkedList为空的时候会抛出NoSuchElementException,而后者会返回null
System.out.println("linkedlist第一个对象:");
System.out.println("linkedlist.getFirst():" + linkedList.getFirst());
System.out.println("linkedlist.element():" + linkedList.element());
System.out.println("linkedlist.peek():" + linkedList.peek());
//然后是移除列表头并返回它
//也有三种removeFirst()、remove()、poll() 同样的前两种在列表为空的时候会抛出Exception,而后者返回null
System.out.println("linkedlist.removeFirst():" + linkedList.removeFirst());
System.out.println("linkedlist.remove:" + linkedList.remove());
System.out.println("linkedlist.poll:" + linkedList.poll());
System.out.println("此时linkedlist为:");
for(int i = 0; i < linkedList.size(); i++)
{
System.out.print(linkedList.get(i) + " ");
}
System.out.println();
//移除最后的对象removeLast()
linkedList.removeLast();
System.out.print("removeLast():" );
for(int i = 0; i < linkedList.size(); i++)
{
System.out.print(linkedList.get(i) + " ");
}
System.out.println();
//添加的方法除了add()之外,还有addFirst()、addLast()、offer()
//addFirst()是添加对象到列表头,add()、addLast()、offer()是添加到列表尾部
linkedList.addFirst(11);
System.out.print("addFirst(11):" );
for(int i = 0; i < linkedList.size(); i++)
{
System.out.print(linkedList.get(i) + " ");
}
System.out.println();
linkedList.addLast(12);
System.out.print("addLast(12):" );
for(int i = 0; i < linkedList.size(); i++)
{
System.out.print(linkedList.get(i) + " ");
}
System.out.println();
linkedList.offer(13);
System.out.print("offer(13):" ); //其实还有offerFirst()、offerLast()...
for(int i = 0; i < linkedList.size(); i++)
{
System.out.print(linkedList.get(i) + " ");
}
System.out.println();
}
}
总的来说,ArrayList和LinkedList很多方法都是一样的(在用法上),毕竟都是继承于List接口,LinkedList的方法相比ArrayList要稍微多一些,最主要的差别其实还是在实现方面,ArrayList里面就是一个数组,而LinkedList就是实打实的写了Node类,由节点组成的。