Java Collections Framework是java很常用和重要的一个知识点,它的所有类和接口都在java.util包中。集合中只能保存对象(保存对象的引用变量)。(数组既可以保存基本类型的数据也可以保存对象)。
当我们把一个对象放入集合中后,系统会把所有集合元素都当成Object类的实例进行处理。从JDK1.5以后,这种状态得到了改进:可以使用泛型来限制集合里元素的类型,并让集合记住所有集合元素的类型(参见具体泛型的内容)
+--java.util.List [I]
+--java.util.ArrayList [C]
+--java.util.LinkedList [C]
+--java.util.Vector [C]
+--java.util.Stack [C]
+--java.util.Set [I]
+--java.util.HashSet [C]
+--java.util.SortedSet [I]
+--java.util.TreeSet [C]
java.util.Map [I]
+--java.util.SortedMap [I]
+--java.util.TreeMap [C]
+--java.util.Hashtable [C]
+--java.util.HashMap [C]
+--java.util.LinkedHashMap [C]
+--java.util.WeakHashMap [C]
Set、List和Map可以看做集合的三大类。
List集合是有序集合,集合中的元素可以重复,访问集合中的元素可以根据元素的索引来访问。
Set集合是无序集合,集合中的元素不可以重复,访问集合中的元素只能根据元素本身来访问(也是不能集合里元素不允许重复的原因)。
Map集合中保存Key-value对形式的元素,访问时只能根据每项元素的key来访问其value。
对于Set、List和Map三种集合,最常用的实现类分别是HashSet、ArrayList和HashMap三个实现类。
2.Collection接口
Collection接口是最基本的容器接口,继承至Iterable接口(主要通过其进行产生迭代器逐一的进行元素访问)。JDK没有提供直接实现Collection接口的实现类。
Iterator it = collection.iterator(); // 获得一个迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一个元素
}
所有实现Colection的类原则上都应该提供两个标准的构造函数:无参构造函数用于创建一个空的容器,有参构造函数用于创建一个新的Collection,且这个新的Collection和传入的collection具有相同的元素。
2.1List接口
元素是有序的,可以重复,因为该集合体系有索引
List特有方法。凡是可以操作角标的方法都是该体系特有的方法。
public static void method(){
ArrayList al=new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
sop("原集合是:"+al);
/*
增
add(index,element);
addAll(index,Collection);
删
remove(index);
改
set(index,element)
查
get(index);
subList(from,to);
listIterator();
List集合特有的迭代器,ListIterator是Iterator的zi
*/
//增
al.add(1,"java09");
//删
al.remove(2);
//改
al.set(2,"java07");
//查
sop("get(1):"+al.get(1));
sop(al);
Iterator it =al.iterator();
while(it.hasNext()){
sop("next:"+it.next());
}
//通过indexOf获取对象的位置
sop("index="+al.indexOf("java07"));
List sub=al.subList(1,3);
sop("sub="+sub);
}
public static void sop(Object obj){
System.out.println(obj);
}
List除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个 ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素, 还能向前或向后遍历。
|--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询速度稍慢。
注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
List list = Collections.synchronizedList(new LinkedList(...));
/*
LinkedList:特有方法:
addFirst();
addLast();
getFirst();
getLast();
//get与remove的区别:get只能获取元素,remove获取元素外,还可以删除元素
removeFirst();
removeLast();
如果集合中没有元素,会出现NoSuchElementException
在jdk1.6出现了替代方法
offerFirst();
offerLast();
获取元素,但不被删除,如果集合中没有元素,会返回null
peekFirst();
peekLast();
获取元素,但元素被删除,如果集合中没有元素,会返回null
pollFirst();
pollLast();
*/
| --Vector:(不建议用)底层是数组数据结构。线程同步,不过用ArrayList加锁即可(功能和ArrayList基本相同,只是版本不同,Vector是jdk1.0)
2.2Set接口——元素是无序(存入和取出的顺序不一定一致),元素不可以重复
|--HashSet:底层数据结构是哈希表。
HashSet是如何保证元素的唯一性呢?!!!!
是通过元素的两个方法,hashCode和equals来完成。如果元素的hashCode值相同,才会判断equals是否为true。如果元素的hashCode值不同,不会调用equals。注意,对于判断元素是否存在或者删除等操作,依赖的方法是元素的hashCode和equals方法。
HashSet不是同步的,需要用以下语句来进行S同步转换:
Set s = Collections.synchronizedSet(new HashSet(...));
|--TreeSet:可以对Set集合中的元素进行排序(按ascii码排)
底层数据结构是二叉树
保证元素的唯一性的依据:compareTo方法return 0.
TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。另一种方式也成为元素的自然排序,或者叫默认排序;
TreeSet的第二种排序方式:当元素自身不具备比较性是,或者具备的比较性不是所需要的,这时就需要让集合自身具备比较性,在集合初始化时,就有比较方式;
import java.util.*;
/*
当元素自身不具备比较性,或者具备的比较性不是所需要的
这时需要让容器自身具备比较性
定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数
当两种排序都存在时,以比较器为主
定义一个类,实现Comparator接口,覆盖coompare方法
*/
class Student implements Comparable{//该接口强制让学生具有比较性
private String name;
private int age;
Student(String name,int age){
this.name=name;
this.age=age;
}
public int compareTo(Object obj){
//怎么存,怎么取
//return 1;
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s=(Student)obj;
//System.out.println(this.name+"...compareTo..."+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age){
return this.name.compareTo(s.name);
}
return -1;
}
public String getName(){
return name;
}
public int getAge(){
return age;
}
}
class TreeSetDemo2{
public static void main(String[] args){
TreeSet ts=new TreeSet(new MyCompare());
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi06",18));
ts.add(new Student("lisi007",29));
//ts.add(new Student("lisi007",20));//重复元素不会添加进去
//ts.add(new Student("lisi01",40));
Iterator it=ts.iterator();
while(it.hasNext()){
//System.out.println(it.next());
Student stu=(Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
class MyCompare implements Comparator{ //实现比较器接口
public int compare(Object o1,Object o2){
Student s1=(Student)o1;
Student s2=(Student)o2;
int num= s1.getName().compareTo(s2.getName());
if(num==0){
//Integer对象也实现了Comparator接口
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return num;
}
}
3.Map接口
Map集合存储键值对。一对一对往里存。而且要保证键的唯一性。
/*
Map集合:该集合存储键值对。一对一对往里存。而且要保证键的唯一性。
1.添加
2.删除
clear()
3.判断
containsValue(Object value)
containsKey(Object key)
isEmpty()
4.获取
get(Object key)
size()
value()
entrySet()
keySet()
Map
|--Hashtble:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的,jdk1.0效率低
|--HashMap:底层是哈希表数据结构,允许使用null值和null键,该集合是不同步的。jdk1.2效率高
|--TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。
和Set很像。
其实,Set底层就是使用了Map集合。
*/
import java.util.*;
class MapDemo{
public static void main(String[] args){
Map<String,String> map=new HashMap<String,String>();
//添加元素,(如果出现添加时,相同的键,那么后添加的只会覆盖原有对应值,并put方法会返回被覆盖的值)
//System.out.println("put:"+map.put("01","zhangsan01")); //结果:null
//System.out.println("put:"+map.put("01","wangwu")); //结果:zhangsan01
map.put("01","zhangsan1");
map.put("02","zhangsan2");
map.put("03","zhangsan3");
System.out.println("containsKey:"+map.containsKey("022"));
//System.out.println("remove:"+map.remove("02"));
System.out.println("get:"+map.get("023"));
//可以通过get方法的返回值来判断一个键是否存在。通过返回null来判断。
map.put("04",null); //HashMap可以存空值null
System.out.println("get:"+map.get("04"));
//获取map集合中所有的值
Collection<String> coll=map.values();
System.out.println(coll);
System.out.println(map);
}
}
---EOF---