Java中的集合类
一、集合框架中的接口:
Collection:集合层次中的根接口,JDK中没有提供这个接口直接的实现类。
Set:不能包含重复元素。SortedSet是一个按照升序排列元素的Set。
List:是一个有序的集合,可以包含重复的元素。提供了按索引访问的方式。
Map:包含了Key—value对。Map不能包含重复的key。SortedMap是一个按照升序排列key的Map。
所谓框架就是一个类库的集合。框架就是一个用来表示和操作集合的统一的框架,包含了实现集合的接口与类
二、Collections类
1、 排序:Collection.sort();
1) 自然排序;
2) 实现比较器;
对象在调用sort这个方法的时候必须实现接口 Comparable ,实现这个接口的时候实现compareTo
例如:import java.util.*;
public class ArrayListTest
{
public static void printElements(Collection c)//用迭代器打印输出
{
Iterator it=c.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
@SuppressWarnings("unchecked")
public static void main(String[] args)
{
Student s1=new Student(6,"zhangsan");
Student s2=new Student(5,"lisi");
Student s3=new Student(7,"wangwu");
ArrayList al=new ArrayList();
al.add(s1);
al.add(s2);
al.add(s3);
Collections.sort(al);//排列比较(al,Collections.reverseOrder())可实现反序排列
printElements(al);//调用函数打印输出
}
}
class Student implements Comparable
{
int num;
String name;
Student(int num,String name)
{
this.num=num;
this.name=name;
}
public int compareTo(Object o)//实现比较
{
Student s=(Student)o;
return num>s.num ? 1 :(num==s.num ? 0 : -1);
}
public String toString()//重写toString返回自定义格式
{
return num+":"+name;
}
}
如果想按自己的比较对象排列可以自己定义比较器例如:
import java.util.*;
public class ArrayListTest
{
public static void printElements(Collection c)//用迭代器打印输出
{
Iterator it=c.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
@SuppressWarnings("unchecked")
public static void main(String[] args)
{
Student s1=new Student(6,"zhangsan");
Student s2=new Student(5,"lisi");
Student s3=new Student(7,"wangwu");
ArrayList al=new ArrayList();
al.add(s1);
al.add(s2);
al.add(s3);
Collections.sort(al,new Student.StudentComparator());//排列比较
printElements(al);//调用函数打印输出
}
}
class Student implements Comparable
{
int num;
String name;
static class StudentComparator implements Comparator//用内部类定义比较器
{
public int compare(Object o1,Object o2)
{
Student s1=(Student)o1;
Student s2=(Student)o2;
return s1.name.compareTo(s2.name);
}
}
Student(int num,String name)
{
this.num=num;
this.name=name;
}
public int compareTo(Object o)//实现比较
{
Student s=(Student)o;
return num>s.num ? 1 :(num==s.num ? 0 : -1);
}
public String toString()//重写toString返回自定义格式
{
return num+":"+name;
}
}
2、 取最大和最小的元素:Collection.max()、Collection.min()比较简单,代码直接由上面的改写就行了,这里我就不去操作了
3、 在已排序的List中搜寻指定元素;Collection.binarySearch()主要用于对数组的操作。
三、ListkedList类
1、 ListkedList是采用双向循环链表实现的
2、 利用ListkedList实现栈、队列、双向队列。
拓展:一般将数据结构分为两大类:现行数据结构和费现行数据结构。现行数据结构有线性表、栈、队列、串、数组和文件;非线性数据结构有树和图。
1) 线性表:①线性表的逻辑结构是n个数据元素的有限序列:(a1,a2,a3,……an),n为线性表的长度(n)=0),n=0表示 线性表为空。
②数据元素呈现线性关系。必存在唯一的称为“第一个”的数据元素;必存在唯一的称为“最后一个”的数据元素;除第一个元素外,每个元素有且只有一个前去元素;除最后一个以外,每个元素有且有唯一的后继元素。
③所有数据元素在同一个线性表中必须是相同数据类型
④线性表按存储结构课分为顺序表和链表。用顺序存储结构存储的线性表称为顺序表;用链式存储结构存储的线性表称为链表。
⑤将线性表中的数据元素一次存放在某个存储区域内,所形成的表称为顺序表。一维数组使用顺序表方式存储的线性表
2) 链表:①单项链表
Next用于存放下一个节点的内存地址,第一个节点称为head节点
②单向循环链表
① 双向循环链表
3) 栈
① 栈是一种特殊的线性表,是一种后进先出的(LIFO)的结构
② 栈是限定仅在表尾进行插入和删除运算的线性表,表尾称为栈顶(top),表头称为栈底(bottom)。
③ 栈的物理存储可以用顺序存储结构,也可以用链式存储结构
下面是一个栈代码:
import java.util.*;
public class MyStack
{
private LinkedList ll = new LinkedList();
public void push(Object o)//入栈
{
ll.addFirst(o);
}
public Object pop()//出栈
{
return ll.removeFirst();
}
public Object peek()//查看栈元素但不移动元素
{
return ll.getFirst();
}
public boolean empty()
{
return ll.isEmpty();
}
public static void main(String[] args)
{
MyStack ms = new MyStack();
ms.push("one");
ms.push("two");
ms.push("three");
ms.push("four");
System.out.println(ms.pop());//调出栈顶元素
System.out.println(ms.peek());//检查栈顶元素
System.out.println(ms.pop());//调出栈顶元素
System.out.println(ms.empty());//检查栈是否为空
}
}
4) 队列:
① 队列(Queue)是限定所有的插入只能在表的一端进行,而所有的删除都是在表的另一端进行的线性表
② 表中允许插入的一端称为队尾(rear),允许删除的一端称为对头(front)。
③ 队里的操作是按先进先出的原则进行的。
④ 队列的物理存储可以用顺序结构,也可以用链式结构。
下面是一个队列的代码:
import java.util.LinkedList;
public class MyQueue
{
private LinkedList ll = new LinkedList();
public void put(Object o)
{
ll.addLast(o);
}
public boolean empty()
{
return ll.isEmpty();
}
public Object get()
{
return ll.removeFirst();
}
public static void main(String[] args)
{
MyQueue l = new MyQueue();
l.put("one");
l.put("two");
l.put("three");
System.out.println(l.get());
System.out.println(l.get());
System.out.println(l.get());
System.out.println(l.empty());
}
}
注:如果向更深层的学习数据结构,刻字机查阅资料,在这里我就不过多介绍了。
四、ArrayList与LinkedList的比较。
1、 ArrayList底层采用数组完成,而LinkedList是以一般的双向链表完成,其内每个对象除了数据本身外还有两个引用,分别指向前一个元素和后一个元素。
2、 如果我们经常在List的开始处增加元素,或者在List中进行插入和删除操作,我们应该使用LinkedList,否则的话,使用ArrayList将更加快速。