Collection:集合层次中的根接口,JDK没有提供这个接口直接的实现类。
Set:不能包含重复的元素。SortedSet是一个按照升序排列元素的Set。
List:是一个有序的集合,可以包含重复的元素。提供了按索引访问的方式。
Map:包含了key-value对。Map不能包含重复的key。SortedMap是一个按照升序排列key的Map。
一般将数据结构分为两大类:线性数据结构和非线性数据结构。线性数据结构有线性表、栈、队列、串、数组和文件;非线性数据结构有树和图。
线性表的逻辑结构是n个数据元素的有限序列:(a1, a2 ,a3,…an)
n为线性表的长度(n≥0),n=0的表称为空表。
数据元素呈线性关系。必存在唯一的称为“第一个”的数据元素;必存在唯一的称为“最后一个”的数据元素;除第一个元素外,每个元素都有且只有一个前驱元素; 除最后一个元素外,每个元素都有且只有一个后继元素。
所有数据元素在同一个线性表中必须是相同的数据类型。
线性表按其存储结构可分为顺序表和链表。用顺序存储结构存储的线性表称为顺序表;用链式存储结构存储的线性表称为链表。
将线性表中的数据元素依次存放在某个存储区域中,所形成的表称为顺序表。一维数组就是用顺序方式存储的线性表。
栈(Stack)也是一种特殊的线性表,是一种后进先出(LIFO)的结构。
栈是限定仅在表尾进行插入和删除运算的线性表,表尾称为栈顶(top),表头称为栈底(bottom)。
栈的物理存储可以用顺序存储结构,也可以用链式存储结构。
队列(Queue)是限定所有的插入只能在表的一端进行,而所有的删除都在表的另一端进行的线性表。
表中允许插入的一端称为队尾(Rear),允许删除的一端称为队头(Front)。
队列的操作是按先进先出(FIFO)的原则进行的。
队列的物理存储可以用顺序存储结构,也可以用链式存储结构。
散列表又称为哈希表。散列表算法的基本思想是:以结点的关键字为自变量,通过一定的函数关系(散列函数)计算出对应的函数值,以这个值作为该结点存储在散列表中的地址。
当散列表中的元素存放太满,就必须进行再散列,将产生一个新的散列表,所有元素存放到新的散列表中,原先的散列表将被删除。在Java语言中,通过负载因子(load factor)来决定何时对散列表进行再散列。例如:如果负载因子是0.75,当散列表中已经有75%的位置已经放满,那么将进行再散列。
负载因子越高(越接近1.0),内存的使用效率越高,元素的寻找时间越长。负载因子越低(越接近0.0),元素的寻找时间越短,内存浪费越多。
HashSet类的缺省负载因子是0.75。
package com.source;
import java.io.FileInputStream;
import java.util.*;
public class CollectionTest {
public static void PrintElements(Collection c){ //使用Iterator迭代器输出集合的内容
Iterator it=c.iterator(); //Collection c用于向上转型
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
public static void main(String args[]){
System.out.println("-------------------------ArrayList-------------------------");
//ArrayList的随机访问元素的效率非常高
ArrayList al=new ArrayList();
al.add(new Family(4,"laoda"));
al.add(new Family(3,"laoer"));
al.add(new Family(3,"laosan"));
al.add(new Family(1,"laosi"));
System.out.println("从”列表“转”数组“");
Object[] o=al.toArray();
for(int i=0;i<o.length;i++){
System.out.print(o[i]+"");
}
System.out.println();
System.out.println();
System.out.println("从”数组“转”列表“");
List l=Arrays.asList(al);
PrintElements(l);
System.out.println();
System.out.println("由Iterator迭代器输出");
Collections.sort(al,new Family.FamilyComparator());
/*实现了Comparable接口的数组列表,可以通过 Collections.sort(List<T> list)方法来进行自动排序
也可以通过Collections.sort(List<T> list, Comparator<? super T> c)增加一个比较器参数来
定义排序规则
*/
//newFamily.FamilyComparator() 加载Family的比较器
//Collections.reverseOrder() 实现倒序排列
PrintElements(al);
System.out.println("-------------------------LinkedList-------------------------");
//可以实现数据结构的栈,双向循环链表等结构,适用于高效的增加删除元素
LinkedList ll=new LinkedList();
System.out.println("构造一个栈,栈:后进先出,先进后出 栈竖形排列 上边为栈顶 下边为栈底");
ll.addFirst(1);
ll.addFirst(2);
ll.addFirst(3);
ll.addFirst(4);
ll.addFirst(5);
PrintElements(ll); //依然使用迭代器输出 也可以sysout直接打印输出 会变为横向数组[4, 3, 2, 1]
System.out.println("删除栈顶元素"+ll.removeFirst());
PrintElements(ll);
System.out.println("查看当前栈顶元素"+ll.getFirst());
System.out.println("-------------------------HashSet-------------------------");
HashSet hs=new HashSet(); //Hashset 称为哈希表 也叫散列表 需要实现hashcode()和equals()方法
hs.add(new Family(4,"laoda"));
hs.add(new Family(3,"laoer"));
hs.add(new Family(3,"laosan"));
hs.add(new Family(1,"laosi"));
hs.add(new Family(1,"laosi"));
PrintElements(hs);
System.out.println("-------------------------TreeSet-------------------------");
TreeSet ts=new TreeSet(new Family.FamilyComparator()); //类似于ArrayList
ts.add(new Family(4,"laoda")); //也需要比较器来比较元素大小
ts.add(new Family(3,"laoer"));
ts.add(new Family(3,"laosan"));
ts.add(new Family(1,"laosi"));
ts.add(new Family(1,"laosi"));
PrintElements(ts);
//Hastset实现了哈希算法优于TreeSet,TreeSet用于元素比较,且set中不能存放相同元素
System.out.println("-------------------------HashMap-------------------------");
HashMap hm=new HashMap();
hm.put(1, "laoda");
hm.put(2, "laoer");
hm.put(3, "laosan");
hm.put(4, "laosi");
System.out.println(hm.get(1)+" "+hm.get(2)+" "+hm.get(3)+" "+hm.get(4));
System.out.println();
System.out.println("HashMap的keySet()方法返回一个Set类型的键的集合");
Set keys=hm.keySet();
PrintElements(keys);
System.out.println();
System.out.println("HashMap的Values()方法返回一个Collection类型的值的集合");
Collection values=hm.values();
PrintElements(values);
System.out.println();
System.out.println("HashMap的entrySet()方法返回一个Map.Entry类型的键值对的集合");
Set entrySet=hm.entrySet();
Iterator it=entrySet.iterator();
while(it.hasNext()){
System.out.println(it.next()); //可以直接用迭代器输出内容
}
while(it.hasNext()){
Map.Entry me=(Map.Entry)it.next(); //也可以用迭代器把结果赋值给Map.Entry类型的对象
System.out.println(me.getKey()+":"+me.getValue());//通过此对象在获取值
System.out.println(me.hashCode());
}
//HashMap的速度通常比TreeMap快,TreeMap用于元素比较,只有在需要排序的时候才用TreeMap
System.out.println("-------------------------Properties-------------------------");
System.out.println("使用Properties返回当前java配置的系统属性");
Properties pp=System.getProperties();
pp.list(System.out);
System.out.println();
System.out.println("使用Properties集合来读取后缀名为.ini的配置文件");
Properties pp2=new Properties();
try{
pp2.load(new FileInputStream("E:/J2EE/Java Workspace/Test/com/source/Properties.ini")); //加载文件
}//读取文件需要使用绝对路径
catch(Exception e){
e.printStackTrace();
}
Enumeration e=pp2.propertyNames();//获取文件的信息,传给一个枚举类型的对象
while(e.hasMoreElements()){
/*需要为中文字符转码 使用JDK/bin目录下的native2ascii.exe程序
例如Collection=/u96c6/u5408
ArrayList=/u6570/u7ec4/u5217/u8868
Set=/u7ec4/u5408
Map=/u6620/u5c04*/
String key=(String)e.nextElement();//获取ini文件中的键的值
String value=(String)pp2.getProperty(key);//根据键来获取值
System.out.println(key+"="+value);//输出ini文件中的结果
}
}
}
class Family implements Comparable{//实现Comparable接口,对实现它的每个类的对象进行整体排序
int num;
String name;
public Family(int num,String name){
this.num=num;
this.name=name;
}
public int compareTo(Object o) {//Comparable的实现方法,可以自定义排序规则
Family f=(Family)o;
return num>f.num ? 1 : (num==f.num) ? 0 : -1;
}
public String toString(){
return num+" "+name;
}
static class FamilyComparator implements Comparator {//实现一个比较器接口Comparator
public int compare(Object o1,Object o2){//Comparator的实现方法 用于比较两个对象
Family f1=(Family) o1;
Family f2=(Family) o2;
int result=f1.num>f2.num ? 1 : (f1.num==f2.num ? 0 : -1);
if(result==0)
return f1.name.compareTo(f2.name);
return result;
}
}
public int hascode(){
return num*name.hashCode();
}
public boolean equals(Object o){
Family f=(Family)o;
return name==f.name && name.equals(f.name);
}
}