---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
一、总体介绍
在Java中集合框架中有基础的两大派系:Collection接口与Map接口,Collection是单值存放的最大接口,可以向其中保存多个单值数据,此接口在开发中很少使用,一般情况下会使用其子接口List,Set,而Map接口则是存放键值对的集合类。常用类的总体继承关系如下:
Collection 提供了集合操作的基本方法
| List 对集合操作的方法做了大量的扩充 【可以存放重复元素】
| ArrayList 非线程安全,查询、修改速度非常快,添加、删除速度稍慢
| LinkedList 非线程安全,添加、删除速度非常快,查询、修改速度稍慢
| Vector 线程安全,效率略慢,但是很容易得到迭代集合早期的接口:Enumeration,通过v.elements();方法获取
| Set 没有对集合方法做扩充【不可以存放重复元素】
| HashSet 该类中不允许存放重复的元素,其比较元素是否重复是调用被添加对象的hashCode()方法,如果hashCode()方法的返回值相同,就会调用对象的equals方法
| TreeSet 本类中判断是否是重复元素的条件是通过判断Comparable接口的compareTo()方法,或者是Comparator接口的cmpare()方法。返回0则表示同一元素
Map
| HashMap 通过判断hashCode() equals()方法判断key值是否重复,如果key值重复,则后添加的方法就会覆盖最先添加的方法。允许key为空
| HashTable 与上述方法一致,key值与value值都不允许为空。
| TreeMap TreeMap与TreeSet一样都要求对象实现Comparable接口或者手动创建具有排序功能的TreeMap(也就是new TreeMap(new Comparator(){public int compateTo()}));
二、对于List操作案例
ArrayList:去除ArrayList中的重复元素
package com.itheima.collection;
import java.util.ArrayList;
import java.util.List;
/**
* ArryList练习1:去除ArrayList中的重复元素
*
*/
public class CollectionDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
for(int i = 0 ;i <10; i++){
list.add("元素 "+ i%2);
}
list = removeRepeat(list);
for (String e : list) {
System.out.println(e);
}
}
/**
* 去掉List中重复数据
* @param list
* @return
*/
public static <T> List<T> removeRepeat(List<T> list){
if(list == null){
throw new NullPointerException("list cannot empty.");
}
List<T> newList = new ArrayList<T>();
for (T t : list) {
//如果新的List集合中包含了该元素,结束本次循环继续下次循环。
if(newList.contains(t)){
continue;
}
//如果新的List集合中没有该元素,直接把该元素添加到新的集合之中。
newList.add(t);
}
return newList;
}
}
当然,上述操作只是最简单的练习, List中contains(obj)方法在实现过程中需要调用对象obj的equals(Object obj)方法,如果没有在子类中重写Object的boolean equals(Object obj)方法,那么就会直接使用Object类的equals()方法, 对于自定义对象,如果想要判断List中是否包含(contans(obj))则需要重写equals方法,否则,结果可能会与预想的不太一样。
LinkedList练习:模拟栈与队列的数据结构
package com.itheima.collection;
import java.util.LinkedList;
/**
* LinkedList练习:模拟一个堆栈与队列
* 栈:先进后出
* 队列:先进先出
*/
public class CollectionDemo2 {
public static void main(String[] args) {
/*MyQueue<String> mQueue = new MyQueue<String>();
mQueue.add("ccc");
mQueue.add("aaa");
mQueue.add("bbb");
while(!mQueue.isEmpty()){
System.out.println(mQueue.remove());
}*/
MyStack<String> mStack = new MyStack<String>();
mStack.add("111");
mStack.add("222");
mStack.add("333");
while(!mStack.isEmpty()){
System.out.println(mStack.remove());
}
}
}
/**
* 自定义队列的实现,采用LinkedList
* 特点:先进先出
*/
class MyQueue<T>{
private LinkedList<T> mQueue;
public MyQueue(){
mQueue = new LinkedList<T>();
}
public void add(T t){
mQueue.addFirst(t);
}
public T remove(){
if(mQueue == null || mQueue.isEmpty()){
return null;
}
return mQueue.removeLast();
}
public boolean isEmpty(){
if(mQueue == null){
return true;
}
return mQueue.isEmpty();
}
}
/**
* 模拟实现栈的结构
* @param <T>
*/
class MyStack<T>{
private LinkedList<T> mStack ;
public MyStack(){
mStack = new LinkedList<T>();
}
public void add(T t){
mStack.addFirst(t);
}
public T remove(){
if(mStack.isEmpty()){
return null;
}
return mStack.removeFirst();
}
//判断是否为栈中是否存在元素
public boolean isEmpty(){
return mStack.isEmpty();
}
}
三、Set操作
在Set接口中有两个比较重要的实现类:HashSet与TreeSet
package com.itheima.collection;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
/**
* Set操作
*/
public class CollectionDemo3 {
public static void main(String[] args) {
Set<Person> set = new HashSet<Person>();
set.add(new Person("zhansan", "----"));
set.add(new Person("zhansan", "----"));
set.add(new Person("zhansan", "----"));
//在没有重写hashCode与equals方法之前这里输出的set的数据数量为3,因为hashSet在判断两个对象是否相等时,是首先根据hashCode()的返回值来判断
//如果hashCode()方法的返回痣相同,则会继续调用equals()方法。
System.out.println(set.size());
TreeSet操作
//Set<Person> mTreeSet = new TreeSet<Person>();
//这里添加元素异常,原因是Person类不能强制转换为Comparable
//所以要想添加元素成功,可以实现Comparable接口
//--
//mTreeSet.add(new Person("111", "ewe"));
//如果想要在TreeSet中添加没有实现Comparable接口的对象?
//可以手动创建一个具有排序功能的TreeSet
Set<Person> mSet = new TreeSet<Person>(new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
int resuleCode = o1.getAddr().compareTo(o2.getAddr());
if(resuleCode == 0){
return o1.getName().compareTo(o2.getName());
}
return resuleCode;
}
});
//尽管Person没有实现Comparable接口,也可以实现元素向TreeSet中的添加。
mSet.add(new Person("23", "3333"));
}
}
class Person/*TreeSet支持,实现Comparable接口之后,在添加元素就不再报错 implements Comparable<Person>*/{
private String name;
private String addr;
public Person(String name,String addr) {
this.name = name;
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
/*@Override
public int compareTo(Person p) {
int resultCode = this.getName().compareTo(p.getName());
if(resultCode == 0){
return this.addr.compareTo(p.getAddr());
}
return resultCode;
}*/
@Override
public int hashCode() {
System.out.println("hashCode() execute.");
final int prime = 31;
int result = 1;
result = prime * result + ((addr == null) ? 0 : addr.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
System.out.println("equals() execute.");
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (addr == null) {
if (other.addr != null)
return false;
} else if (!addr.equals(other.addr))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
四、Map操作
对于Map接口,最长用的类就是HashMap,其次是TreeMap,还要知道一个与HashMap功能完全一样的类就是HashTable【这样说可能不太合理】
关于HashMap与Hashtable,底层都是使用了hash算法,HashMap是异步的,HashTable是同步的,所以HashMap的效率要比HashTable的效率要高,还有就是HashMap允许存放null的key与value,而HashTable的key与value都不能为null,否则,会出现空指针异常。
1.HashMap的基本操作--map的数据迭代,不能直接使用Iterator。
package com.itheima.collection;
import java.util.HashMap;
import java.util.Map;
public class CollectionDemo4 {
public static void main(String[] args) {
Map<String,String> map = new HashMap<String, String>();
for(int i = 0;i<10;i++){
//添加元素
map.put("key"+i, "value"+i);
}
//使用加强for循环输出Map中的元素,也可以使用map.entrySet();得到Map.Entry<String,String>的getKey(),getValue()
//方法获取key 与value
for (String key : map.keySet()) {
System.out.println(map.get(key));
}
//注意hashMap中,如果key值相同,后添加的元素的value值会覆盖前面的元素,比较key值是否相同,hashMap
//会首先调用被操作对象的hashCode()方法,如果hashCode()方法的返回值相同的话,会继续调用被操作对象
//的equals()方法,如果此时equals()方法的返回值为true,则hashMap就会认为这 是不同的key
//map的其他操作,可以多加练习,慢慢熟练。
//HashTable与HashMap基本操作一致的。最后,关于TreeMap的使用,自我感觉很少使用,但是需要注意一点,TreeMap添加元素时,如果元素对象没有实现 //Comparable接口的话,需要建立具有比较功能的TreeMap对象才能进行元素的添加。不管是TreeMap,TreeSet都是会对元素进行二叉树排序的,第一个添加的元素作为根节点///,而后添加的元素,如果比根节点的元素大,就会插入到根节点的右侧,否则左侧。。
}
}
五、集合框架的工具类
在集合框架中有两个非常常用的工具类Collections与Arrays,关于这两个工具类的使用,只利用很常用的两个方法来说明下:Collections.sort(List,Comparetor)排序,Arrays.asList(T...t) ;其他方法,查看JavaAPI文档可以慢慢练习。
六、总结
1.List扩展了Collection接口,里面允许存放重复数据,List接口常用的子类有ArrayList、LinkedList、Vector在开发中ArrayList的性能要比Vector的性能高,因为ArrayList是异步的,Vector是同步的。
2.Set接口与Collection接口是一致的,里面不允许存放重数据,判断数据是否重复,需要调用对象的hashCode()与equals()方法,常用的子类有HashSet,TreeSet,前者是散列存放,后者依靠Comparable接口排序后有序存放。注意:set集合可以求出两个即可得差集与交集
3.集合的输出需要使用到Iterator接口完成,Iterator接口数据迭代输出接口
4.在jdk1.5之后可以使用加强for循环进行输出
5.Enumeration接口是早期的迭代输出接口,现在很少使用,类集中Vector可以使用其迭代输出
6.ListIterator接口可以迭代list元素,并且可以使用里面的增、删方法修改list
7.Map接口是存放一组key--value的数据的容器,其中每个实例都是一个Map.Entry,Map常用子类有HashMap,TreeMap,HashTable
8.集合框架中有两个常用的非常重要的工具类,Collections与Arrays,里面封装了大量的集合操作类,例如排序等。
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
详细请查看:http://edu.csdn.net