您的位置:首页 > 职场人生

黑马程序员--java学习之集合框架

2012-06-19 17:38 555 查看
---------------------- android培训java培训、期待与您交流! ----------------------

一.集合框架概述
集合框架就是容器,用来装对象,各种容器中对数据的处理存储方式有所不同。即数据结构不同,集合框架支持3种类型的集合:规则集(Set),线性表(List),和图(Map),分别定义在Set,List,Map中。Set实例存储一组互不相同的元素(集合),List实例存储一组顺序排列的元素(表),Map存储一组对象---关键值的映射:


总的架构如下,非常重要,包含继承关系,实现的分类,一目了然:

Collection接口: 

Set接口:元素是无序,元素不可以重复。

HashSet:底层数据结构是哈希表。是线程不安全的。不同步。HashSet是如何保证元素唯一性的呢?是通过元素的两个方法,hashCode和equals来完成。如果元素的HashCode值相同,才会判断equals是否为true。如果元素的hashcode值不同,不会调用equals。这个equals方法是覆盖Object的,而Object不带泛型,所以在equals方法中必须强制转换类型,注意,对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法。
TreeSet:可以对Set集合中的元素进行排序,线程非同步。底层数据结构是二叉树,保证元素唯一性的依据:compareTo方法
 
List接口:实现链表、队列、堆栈的数据结构。            
ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步,多线程应用时需要锁,初始容量为10个对象元素,超过的话每次自增50%。
  LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。
  Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低,集合框架存在之前就已经有了
 
Map接口:
   HashMap:底层是哈希表数据结构,允许使用
null 值和 null键,该集合是不同步的。    将hashtable替代,从jdk1.2开始有此集合,.效率高。
     TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。 
Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的,.效率低。
 
Set和List对比:
Set:检索元素效率低下,删除和插入效率高,插入和删除不会引起元素位置改变。无序,所存对象唯一,不可以重复存放。
List:和数组类似,List可以动态增长,查找元素效率高,插入删除元素效率低,因为会引起其他元素位置改变。有序可以重复存放。    

 

一.Collection接口的共性方法:
1,添加
      boolean add(e);
      boolean addAll(collection);
 
2,删除
      boolean 
remove(e);
      boolean 
removeAll(collection);
      void clear();
 
3,判断。
      contains(e);
      isEmpty();
 
4,获取
      iterator();
      size();
 
5,获取交集。
      retainAll();
 
6,集合变数组。
      toArray();
三.有关迭代器的知识点:
其实就是集合的取出元素的方式。各种集合容器的数据结构不同,所以取出数据
的动作也不同,但都有共性的需要就是判断取出,在容器内部专门定义了内部类用以
实现这些共性的需要,这些内部类都符合一个规则,该规则就是Iterator接口,通过此接
口对外提供的方法iterator()即可实现需要,此即为迭代,就如同抓娃娃游戏机中的夹子。迭代器是取出方式,会直接访问集合中的元素,所以将迭代器通过内部类的形式来进行描述。
通过容器的iterator()方法获取该内部类的对象。ListIterator是Iterator的子接口。在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常。所以,在迭代器时,只能用迭代器的放过操作元素,可是Iterator方法是有限的,
只能对元素进行判断,取出,删除的操作,如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator。该接口只能通过List集合的listIterator方法获取。
示例代码:
import java.util.*;
class ListDemo
{
public static void sop(Object obj)
{
System.out.println(obj);
}

public static void main(String[] args)
{

//演示列表迭代器。
ArrayList al = new ArrayList();
//添加元素
al.add("java01");
al.add("java02");
al.add("java03");

sop(al);
ListIterator li = al.listIterator();
while(li.hasNext())
{
Object obj = li.next();

if(obj.equals("java02"))
li.set("java006");
}
//在迭代过程中,准备添加或者删除元素。

Iterator it = al.iterator();

while(it.hasNext())
{
Object obj = it.next();

if(obj.equals("java02"))
it.remove();//将java02的引用从集合中删除了
sop("obj="+obj);
}
sop(al);
}
}

四.LinkedList
特有方法有addFirst();addLast();getFirst();getLast();这些方法获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException,在JDK1.6出现了替代方法,包括offerFirst();offerLast();peekFirst();peekLast();
小练习:使用LinkedList模拟一个堆栈或者队列数据结构。
import java.util.*;
class DuiLie
{
private LinkedList link;

DuiLie()
{
link = new LinkedList();
}

public void myAdd(Object obj)
{
link.addFirst(obj);//添加数据总是添加在第一个角标位置上
}
public Object myGet()
{
return link.removeFirst();//删除数据也总是删除第一个位置
}
public boolean isNull()
{
return link.isEmpty();
}
}

class  LinkedListTest
{
public static void main(String[] args)
{
DuiLie dl = new DuiLie();
dl.myAdd("java01");
dl.myAdd("java02");
dl.myAdd("java03");
dl.myAdd("java04");

while(!dl.isNull())
{
System.out.println(dl.myGet());
}
}
}

五.HashSet
      示例:
import java.util.*;
/*
往hashSet集合中存入自定对象
姓名和年龄相同为同一个人,重复元素。
*/
class HashSetTest
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
HashSet hs = new HashSet();

hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a2",12));
hs.add(new Person("a4",14));
hs.remove(new Person("a4",13));

Iterator it = hs.iterator();
while(it.hasNext())
{
Person p = (Person)it.next();
sop(p.getName()+"::"+p.getAge());
}
}
}
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}

public int hashCode()//底层会先调用此方法进行判断两个对象元素的Hashcode是否一样
{
System.out.println(this.name+"....hashCode");
return name.hashCode()+age*37;
}

public boolean equals(Object obj)  //若加入hashset的元素的哈希值相同,则hashaset底层会自动调用此方法
{

if(!(obj instanceof Person))
return false;

Person p = (Person)obj;
System.out.println(this.name+"...equals.."+p.name);

return this.name.equals(p.name) && this.age == p.age;
}

public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}

六:TreeSet
可以对Set集合中的元素进行排序,TreeSet排序的第一种方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo方法。这种方式也成为元素的自然顺序,或者叫做默认顺序。
示例代码:
class TreeSetDemo
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();

ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi08",19));
Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}

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)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;//强制类型转换
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;
}
}

第二种方式:让元素类实现Comparator接口,并覆盖compare方法。当元素自身不具备比较性,或者具备的比较性不是所需要的。这时需要让容器自身具备比较性。定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。
 
示例代码:
class TreeSetDemo2
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet();

ts.add(new Student("lisi02",22));
ts.add(new Student("lisi02",21));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi06",18));
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())
{
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)
{
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return num;
}
}

七.Map集合
map集合的两种取出方式:
1,Set<k>
keySet:将map中所有的键存入到Set集合。因为set具备迭代器。所有可以迭代方式取出所有的键,在根据get方法。获取每一个键对应的值。Map集合的取出原理:将map集合转成set集合。在通过迭代器取出。
 
2,Set<Map.Entry<k,v>>
entrySet:将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry,set集合中存储的都是Map.Entry的实例对象,Map.Entry其实就是Map中的一个static内部接口。为什么要定义在内部呢?因为只有有了Map集合,有了键值对,才会有键值的映射关系。关系属于Map集合中的一个内部事物。而且该事物在直接访问Map集合中的元素。
 
3.HashMap与TreeMap应用详解
      HashSet应用的示例代码:
import java.util.*;
class MapDemo2
{
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String,String>();
map.put("02","zhangsan2");
map.put("03","zhangsan3");
map.put("01","zhangsan1");
map.put("04","zhangsan4");

//将Map集合中的映射关系取出。存入到Set集合中,这是第二种取出方式
Set<Map.Entry<String,String>> entrySet = map.entrySet();
Iterator<Map.Entry<String,String>> it = entrySet.iterator();
/*第一种取出方式的写法:
//先获取map集合的所有键的Set集合,keySet();
Set<String> keySet = map.keySet();
//有了Set集合。就可以获取其迭代器。
Iterator<String> it = keySet.iterator();

*/
while(it.hasNext())
{
Map.Entry<String,String> me = it.next();
String key = me.getKey();
String value = me.getValue();

System.out.println(key+":"+value);

}
}
}

TreeMap在应用时,多了排序的功能,而且它是根据键的元素排序的,相应的,健的元素需要实现Comparable或者Comparator接口,具体与TreeSet类似。
      示例代码:
/*
需求:对学生对象的年龄进行升序排序。

因为数据是以键值对形式存在的。
所以要使用可以排序的Map集合。TreeMap。
*/
import java.util.*;

class StuNameComparator implements Comparator<Student>
{
public int compare(Student s1,Student s2)
{
int num = s1.getName().compareTo(s2.getName());
if(num==0)
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));

return num;
}
}

class  MapTest2
{
public static void main(String[] args)
{
TreeMap<Student,String> tm = new TreeMap<Student,String>(new StuNameComparator());

tm.put(new Student("blisi3",23),"nanjing");
tm.put(new Student("lisi1",21),"beijing");
tm.put(new Student("alisi4",24),"wuhan");
tm.put(new Student("lisi1",21),"tianjin");
tm.put(new Student("lisi2",22),"shanghai");
Set<Map.Entry<Student,String>> entrySet = tm.entrySet();
Iterator<Map.Entry<Student,String>> it = entrySet.iterator();
while(it.hasNext())
{
Map.Entry<Student,String> me = it.next();
Student stu = me.getKey();
String addr = me.getValue();
System.out.println(stu+":::"+addr);
}
}
}

---------------------- android培训java培训、期待与您交流! ----------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息