黑马程序员——java第十四、五、六天:集合框架(一:Collection、Map)

------- android培训java培训、期待与您交流! ----------

Collection体系描述

对象可以放在数组和集合中。

集合的特点:

1、  集合中只用来存储对象,

2、  集合长度是可变的

3、  集合可以存储不同类型的对象。、

 

集合体系:                             

集合框架:

         为什么会出现这么多的容器呢?

因为每个容器对数据的存储方式都有不同,这个存储方式称为数据结构。

 

共性方法

创建一个集合容器,示例使用Collection接口的子类——ArrayList

ArrayList al1=new ArrayList();

1、  添加元素:add(Objectob);

al1.add(“java01”);

al1.add(“java02”);

al1.add(“java03”);

al1.add(“java04”);

2、  获取个数,集合长度

al1.size();

 

内存结构:

 

(1)      add方法的参数类型是ObjectaddObject ob),以便于接收任意类型对象。

(2)      集合中存储的都是对象的引用(地址)

 

打印集合:System.out.println(al1);

 

3、  删除元素:

al1.remove(“java01”);

al1.clear();//清空集合

al1.removeAll(al2);al1中只会保留在al2中没有的元素。

4、  判断元素

al1.contains(“java01”);al1中有没有java01对象

al1.isEmpty();//al1是否为空。

5、  取交集

ArrayList al2=new ArrayList();

al2.add(“java01”);

al2.add(“java02”);

al2.add(“java05”);

al2.add(“java06”);

al1.retainAll(al2);//取交集al1中只会保留和al2中相同的元素。

迭代器

什么是迭代器?

         其实就是集合取出元素的方式。

 

Iterator it=al1.iterator();//获取迭代,用于取出集合中的元素。

whileit.hasNext(){

         System.out.println(it.nex());

}

it.hasNext();//判断如果仍有元素可迭代,则返回true

开发是通常不用while循环而用for循环,因为it迭代以后就没用了所以定义成局部变量比较合适。

forIteratorit=al1.iterator();it.hasNext();{

         System.out.println(it.next());

}

List集合共性方法

List:元素是有序的;元素可以重复,因为该集合体有索引。

set:元素无序,元素不可以重复

 

List特有方法:凡可以操作脚标的方法都是该体系特有方法。

1、  增:

add(index,element);

addAll(index,Collection);

2、  删:

remove(index);

3、  改:

set(index,element);

4、  查:

get(index);

subList(from,to);

listIterator();

例:

forint x=0;x<al1.size();x++{

           System.out.println(al1.get(x));

}

上例所实现得到的功能用Collection中的方法实现

forIterator it=al1.Iterator();it.hasNext();{

           System.out.println(it.nex());

}

ListIterator

通过indexOf获取对象的位置。

例如:al1.indexOf(“java02”);

获得子集合:List sub=al1.subList(1,3);

 

当操作一个集合元素时,只能用一种方式操作(要么是迭代器的方法,要么是集合对象的方法),因为不能并发进行,否则会出现异常。

例如:Interator it=al1.iterator();

while(it.hasNext()){

         Objectobj=it.Next();//迭代器的方法

         if(obj==”java02”)

                   //al1.add(“java008”);//集合对象的方法,这样会异常,所以用下面迭代器方法

                   it.remove();

         System.out.println(al1);//测试打印的是没有移除前的集合元素,因为it.remove();

//时只删除了集合中”java02”的引用,但”java02”还在obj中所使//用,所以才打印出来了

}

System.out.println(al1);//此时打印是删除后的集合元素。

 

List集合特有的迭代器——ListIteratorIterator的子接口。

 

在迭代时,不可以通过集合对象的方法操作集合中的元素。

因为会发生ConcurrentModificationException异常。

 

所以,在迭代器时,只能用迭代器的放过操作元素,可是Iterator方法是有限的,

只能对元素进行判断,取出,删除的操作,

如果想要其他的操作如添加,修改等,就需要使用其子接口,ListIterator

 

该接口只能通过List集合的listIterator方法获取。

 

ListIterator迭代器修改后的代码:

ListInterator li=al1.listIterator();

while(li.hasNext()){

         Objectobj=it.Next();

         if(obj.equals(“java02”))

                   li.set(“java008”);

}

List集合中在操作指针之前,指针是在最右边元素的右边一个位置上的。

所以用hasNext()Next()是会右移。

ListIterator中有个方法与hasNext()Next()完全相反的方法——hasPrevious()和Previous()。他是倒叙迭代的,因为指针(如上),所以迭代时注意。

 

List集合具体对象的特点

|--List:元素是有序的,元素可以重复。因为该集合体系有索引。

|--ArrayList:底层的数据结构使用的是数组结构。特点:查询速度很快。但是增删稍慢。线程不同步。

|--LinkedList:底层使用的链表数据结构。特点:增删速度很快,查询稍慢。线程不同步。

                   |--Vector:底层是数组数据结构。线程同步。被ArrayList替代了。因为效率低。

 

注意:ArrayListVector因为是数组结构,数组长度不可变,所以当往里添加元素超过数组长度时他们会创建新的数组,把旧数组的元素拷过去。ArrayList初始长度是10,每延长一次数组长度增加50%Vector初始长度是10,每延长一次数组长度增加100%

 

Vector:

APIVector下的方法带有element的方法都是其特有方法。

枚举(Enumeration: Elements下的Enumeration的方法hasMoreElements();nextElements();此方法为Vector特有的取出方式。发现枚举和迭代器很像,其实枚举和迭代器是一样的。因为枚举的名称以及方法的名称都过长,所以被迭代器取代了。

        

LinkedList:

         LinkedList:特有方法:

addFirst();

addLast();

 

getFirst();

getLast();

获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementException

 

removeFirst();

removeLast();

获取元素,但是元素被删除。如果集合中没有元素,会出现NoSuchElementException

 

 

JDK1.6出现了替代方法。

 

offerFirst();代替addFirst();

offerLast();代替addLast();

 

 

peekFirst();代替getFirst();

peekLast();代替getLast();

获取元素,但不删除元素。如果集合中没有元素,会返回null

 

pollFirst();代替removeFirst();

pollLast();代替RemoveLast();

获取元素,但是元素被删除。如果集合中没有元素,会返回null

 

例题:

/*

使用LinkedList模拟一个堆栈或者队列数据结构。

 

堆栈:先进后出  如同一个杯子。

队列:先进先出 First in First out  FIFO 如同一个水管。

*/

 

import java.util.*;

class DuiLie

{

         privateLinkedList link;

 

         DuiLie()

         {

                   link= new LinkedList();

         }

         

         publicvoid myAdd(Object obj)

         {

                   link.addFirst(obj);

         }

         publicObject myGet()

         {

                   returnlink.removeFirst();

         }

         publicboolean isNull()

         {

                   returnlink.isEmpty();

         }

 

}

 

 

 

class LinkedListTest

{

         publicstatic void main(String[] args) 

         {

                   DuiLiedl = new DuiLie();

                   dl.myAdd("java01");

                   dl.myAdd("java02");

                   dl.myAdd("java03");

                   dl.myAdd("java04");

 

                   while(!dl.isNull())

                   {

                            System.out.println(dl.myGet());

                   }

         }

}


 

 

 

例二:

package exception;

import java.util.*;

 

class Person{

   private String name;

   privateintage;

   Person(Stringname,intage){

      this.name=name;

      this.age=age;

   }

   publicboolean equals(Object obj){//由于Object中定义的equals

                               //方法只是比较地址值,此处重写比

//较姓名和年龄。

      if(!(obj instanceof Person)){

         returnfalse;

      }

      Personp=(Person)obj;

      returnthis.name.equals(p.name)&&this.age==p.age;

   }

   public String getName() {

      returnname;

   }

   publicint getAge() {

      returnage;

   }     

}

 

 

publicclassArrayListText2 {

   

   publicstaticvoid sop(Object obj){

      System.out.println(obj);

   }

      

   publicstatic ArrayListsingleElement(ArrayList al){

      ArrayListnewAl=newArrayList();

      Iteratorit=al.iterator();

      while(it.hasNext()){

         Objectobj=it.next();

         if(!newAl.contains(obj)){//contains方法中用到了equals

//方法,因为比较姓名和年龄所以上面才重写了equals方法。因为newAl中的

//对象都是Person的对象所以调用时也是Person类中的equals,所以才在

//Person中重写equals的

            newAl.add(obj);

         }

      }

      return newAl;

      

   }

   publicstaticvoid main(String[] args) {

      ArrayListal=newArrayList();

      al.add(new Person("lisi01",30));

      al.add(new Person("lisi01",30));

      al.add(new Person("lisi02",31));

      al.add(new Person("lisi03",32));

      al.add(new Person("lisi03",32));

      al.add(new Person("lisi04",33));

      

      

      al=singleElement(al);

       

      Iteratorit=al.iterator();

      

      while(it.hasNext()){

         Personp=(Person)it.next();//因为add(Object obj)接收的

//对象时用到了多态的上转型,所以要想用到Person中的方法getName等所以

//要向下转型。

         sop(p.getName()+"::"+p.getAge());

         

      }

 

   }

 

}


 

 

HashSet

|--Set:元素是无序(存入和取出的顺序不一定一致),元素不可以重复。、

         |--HashSet:底层数据结构是哈希表。是线程不安全的。不同步。

                            HashSet是如何保证元素唯一性的呢?

                            是通过元素的两个方法,hashCodeequals来完成。

                            如果元素的HashCode值相同,才会判断equals是否为true

                            如果元素的hashcode值不同,不会调用equals

 

 

                            注意,对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcodeequals方法。

所以在自定义对象时如果要存放在hashSet集合中,通常要复写hashCadeequals方法。

 

 

例子:

class HashSetTest 

{

         publicstatic void sop(Object obj)

         {

                   System.out.println(obj);

         }

         publicstatic void main(String[] args) 

         {

                   HashSeths = new HashSet();

 

                   hs.add(newPerson("a1",11));

                   hs.add(newPerson("a2",12));

                   hs.add(newPerson("a3",13));

//               hs.add(newPerson("a2",12));

//               hs.add(newPerson("a4",14));

 

                   //sop("a1:"+hs.contains(newPerson("a2",12)));

                            

//               hs.remove(newPerson("a4",13));

                   

 

                   Iteratorit = hs.iterator();

 

                   while(it.hasNext())

                   {

                            Personp = (Person)it.next();

                            sop(p.getName()+"::"+p.getAge());

                   }

         }

}

class Person

{

         privateString name;

         privateint age;

         Person(Stringname,int age)

         {

                   this.name= name;

                   this.age= age;

         }

         

         publicint hashCode()

         {

                   System.out.println(this.name+"....hashCode");

                   returnname.hashCode()+age*37;

         }

 

         publicboolean equals(Object obj)

         {

 

                   if(!(objinstanceof Person))

                            returnfalse;

 

                   Personp = (Person)obj;

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

 

                   returnthis.name.equals(p.name) && this.age == p.age;

         }

 

         

         publicString getName()

         {

                   returnname;

         }

         publicint getAge()

         {

                   returnage;

         }

}



|--

TreeSet

         |--TreeSet:底层数据结构是二叉树。

 

 

TreeSet排序的第一种方式:让元素自身具备比较性。

                                     元素需要实现Comparable接口,覆盖compareTo方法。

                                     也种方式也成为元素的自然顺序,或者叫做默认顺序。

 

public interface Comparable:此接口强行对实现他的每个类的对象进行整体自然排序。

返回:保证元素唯一性的依据是compareTo方法返回0.可以对Set集合中的元素进行自然排序。

负整数、零或正整数,根据此对象是小于、等于还是大于指定对象。

要放进TreeSet集合中的对象所属的类必须实现Comparable接口,并实现这个接口中的int comparableT o)方法o为比较的对象。以规定按对象的什么属性排序。

TreeSet集合在往这个集合中添加元素时,会在底层调用comparableTo方法。

 

 

 

                                     TreeSet的第二种排序方式。

                                     当元素自身不具备比较性时,或者具备的比较性不是所需要的。

                                     这时就需要让集合自身具备比较性。

                                     在集合初始化时,就有了比较方式。

 

当元素自身不具备比较性,或者具备的比较性不是所需要的。

这时需要让容器自身具备比较性。

定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数。

当两种排序都存在时,以比较器为主。

定义一个类,实现Comparator接口,覆盖compare方法。

 

排序第一种示例:

需求:

TreeSet集合中存储自定义对象学生。

想按照学生的年龄进行排序。

 

 

记住,排序时,当主要条件相同时,一定判断一下次要条件。

 

 

*/

 

class TreeSetDemo 

{

         publicstatic void main(String[] args) 

         {

                   TreeSetts = new TreeSet();

 

                   ts.add(newStudent("lisi02",22));

                   ts.add(newStudent("lisi007",20));

                   ts.add(newStudent("lisi09",19));

                   ts.add(newStudent("lisi08",19));

 

                   Iteratorit = ts.iterator();

                   while(it.hasNext())

                   {

                            Studentstu = (Student)it.next();

                            System.out.println(stu.getName()+"..."+stu.getAge());

                   }

         }

}

 

 

class Student implements Comparable//该接口强制让学生具备比较性。

{

         privateString name;

         privateint age;

 

         Student(Stringname,int age)

         {

                   this.name= name;

                   this.age= age;

         }

 

         publicint compareTo(Object obj)

         {

 

                   //return0;

                   

                   if(!(objinstanceof Student))

                            thrownew RuntimeException("不是学生对象");

                   Students = (Student)obj;

 

                   System.out.println(this.name+"....compareto....."+s.name);

                   if(this.age>s.age)

                            return1;

                   if(this.age==s.age)

                   {

                            returnthis.name.compareTo(s.name);

                   }

                   return-1;

                   /**/

         }

 

         publicString getName()

         {

                   returnname;

 

         }

         publicint getAge()

         {

                   returnage;

         }

}

 



排序第二种示例:

 

import java.util.*;

class Student implements Comparable//该接口强制让学生具备比较性。

{

         privateString name;

         privateint age;

 

         Student(Stringname,int age)

         {

                   this.name= name;

                   this.age= age;

         }

 

         publicint compareTo(Object obj)

         {

 

                   //return0;

                   

                   if(!(objinstanceof Student))

                            thrownew RuntimeException("不是学生对象");

                   Students = (Student)obj;

                   if(this.age>s.age)

                            return1;

                   if(this.age==s.age)

                   {

                            returnthis.name.compareTo(s.name);

                   }

                   return-1;

         }

 

         publicString getName()

         {

                   returnname;

         }

         publicint getAge()

         {

                   returnage;

         }

}

class TreeSetDemo2 

{

         publicstatic void main(String[] args) 

         {

                   TreeSetts = new TreeSet(new MyCompare);// 当两种排序都存在时,以比较器为主。//newMyCompare为定义的比较器类。空参数的为compareTo方法比较。

                   ts.add(newStudent("lisi02",22));

                   ts.add(newStudent("lisi02",21));

                   ts.add(newStudent("lisi007",20));

                   ts.add(newStudent("lisi09",19));

                   ts.add(newStudent("lisi06",18));

                   ts.add(newStudent("lisi06",18));

                   ts.add(newStudent("lisi007",29));

 

                   Iteratorit = ts.iterator();

                   while(it.hasNext())

                   {

                            Studentstu = (Student)it.next();

                            System.out.println(stu.getName()+"..."+stu.getAge());

                   }

         }

}

 

class MyCompare implements Comparator//定义比较器

{

         publicint compare(Object o1,Object o2)

         {

                   Students1 = (Student)o1;

                   Students2 = (Student)o2;

 

                   intnum = s1.getName().compareTo(s2.getName());

                   if(num==0)

                   {

                            returnnew Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));

                            /*

                            if(s1.getAge()>s2.getAge())

                                     return1;

                            if(s1.getAge()==s2.getAge())

                                     return0;

                            return-1;

                            */

                   }

                   returnnum;

         }

}


 

 

泛型

基本数据类型可以放在addObject obj)中做参数,因为1.5jdk以后基本数据类型可以自动装箱封装成对象。

 

泛型:jdk1.5版本出现的新的特性。

         用于解决安全问题,是一个安全机制。

         因为集合中可以存放许多类型的对象,而这些对象有有不同的方法。

比如:

         求字符串的长度,当it.Next()从集合中取出对象时势必要向下转型为在string类型再调用String特有的length()方法求长度,当其中集合中有一个基本数据类型对象被取出再转成String类型时会出现异常,所以演化出来泛型。

 

泛型:ArrayList<String> al=new ArrayList<String>();定义一个ArrayList容器,容器中的元素为String类型,这样在add()时就有了赛选。

 

泛型好处:

1、  将运行时期出现问题ClassCastException转移到了编译时期,方便于程序员解决问题。让运行时异常相对减少,安全。

2、  避免了强制转换麻烦。

 

实例1

class GenericDemo 

{

         publicstatic void main(String[] args) 

         {

 

                   ArrayList<String> al = new ArrayList<String>();

 

                   al.add("abc01");

                   al.add("abc0991");

                   al.add("abc014");

 

                   //al.add(4);//al.add(newInteger(4));

                   

 

                   Iterator<String> it = al.iterator();

                   while(it.hasNext())

                   {

                            Strings = it.next();

 

                            System.out.println(s+":"+s.length());

                   }

         }

}


 

 

 

实例二:

import java.util.*;

class GenericDemo2 

{

         publicstatic void main(String[] args) 

         {

                   TreeSet<String>ts = new TreeSet<String>(new LenComparator());

 

                   ts.add("abcd");

                   ts.add("cc");

                   ts.add("cba");

                   ts.add("aaa");

                   ts.add("z");

                   ts.add("hahaha");

 

 

                   Iterator<String>it = ts.iterator();

 

                   while(it.hasNext())

                   {

                            Strings = it.next();

                            System.out.println(s);

                   }

         }

}

 

class LenComparator implementsComparator<String>//遇上个实力比较的亮点

{

         publicint compare(String o1,String o2)

         {

                   intnum = new Integer(o2.length()).compareTo(new Integer(o1.length()));

 

                   if(num==0)

                            returno2.compareTo(o1);

                   returnnum;

         }

}


 

 

泛型格式:通过<>来定义要曹祝的应用数据类型。

 

在使用java提供的对象时,什么时候写泛型呢?

         通常在集合框架中常见,只要在jdk中见到<>就要定义泛型。其实<>就是用来接收类型的。

         当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。

 

泛型类

什么时候定义泛型类?

         当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展,现在定义泛型类完成扩展。

例:

 

class Work{

         

}

class Student{

}

class Utils<QQ>{

         privateQQ q;

         publicvoid setObject(QQ q){

                   this.q=q;

}

public QQgetObject(){

         return q;

}

}

class GenericDemo{

         publicstatic void main(String[] args){

                   Utils<Worker>u=new Utils<Worker>();

                   u.setObject(newWorker());

                   Workw=u.getObject();

         }

}


 

 

以上事例是:泛型类定义的泛型在整个类中有效。如果北方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定。

 

泛型方法

为了让不同方法可以操作不同类型,而且类型还不确定,呢么可以将泛型定义在方法上。

 

特殊之处:静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。

泛型定义在方法上时要放在返回值前面,修饰符后面。

示例:

class Demo<t>{

         publicvoid show(T t){

                   System.out.println(“show:”+t);

         }

         public<Q> void print(Q q){

                   System.out.println(“print”+9);

         }

         publicstatic <w> void method(W t){

                   Systm.put.println(“method:”+t);

         }

}

class GenericDemo4{

         publicstatic void main(String[] args){

                   Demo<String>d=new Demo<String>();

                   d.show(“haha”);

                   d.print(5);

                   d.print(“hehe”);

                   Demo.method(“hahahh”);

         }

}


 

 

泛型定义在接口上。

interface Inter<T>

{

         voidshow(T t);

}

 

/*//实现方法一:知道操作什么对象

class InterImpl implementsInter<String>

{

         publicvoid show(String t)

         {

                   System.out.println("show:"+t);

         }

}

 

*/

//实现方法二:不知道操作什么对象

class InterImpl<T> implementsInter<T>

{

         publicvoid show(T t)

         {

                   System.out.println("show:"+t);

         }

}

class GenericDemo5 

{

         publicstatic void main(String[] args) 

         {

 

                   InterImpl<Integer>i = new InterImpl<Integer>();

                   i.show(4);

                   //InterImpli = new InterImpl();

                   //i.show("haha");

         }

}


 

 

泛型限定

<?>:通配符或占位符。

泛型的限定:

         extends E :为上限定—可以接收E类型或E类型的子类型。

         super E:为下限定——可以接收E类型或E的父类型。

 

例一:<?>

class GenericDemo{

         publicstatic void main(String[] args){

                   ArrayList<String>al=new ArrayList<String>();

                   al.add(“abc1”);

                   al.add(“abc2”);

ArrayList<Integer> al1=new ArrayList<Integer>();

                   al1.add(4);

                   al1.add(0);

         }

         publicstatic void printColl(ArrayList<?> al){// <?>不知道要传入什么类型对象,

//但什么类型都能接收,相当于占着位置

                   //此处也可写publicstatic <t> void printColl(ArrayList<T> al){

                   //这样写他可以做到:Tt=it.next();t.toString();而<?>不行。还不能使用类型特有方法。

                   for(Iterator<?>it=al.iterator();it.HasNext();){

                            System.out.println(it.next());

}

         }

}


 

 

 

例二:只接收父类及其子类

 

class Person{

         Person(Stringname){

                   this.name=neme;

         }

         publicSreing getName(){

                   returnname();

         }

}

class Student extends Person{

         Student(String name){

                   super(name);

         }

}

class GenericDemo6

{

         publicstatic void main(String[] args) 

         {ArrayList<Person> al = new ArrayList<Person>();

                   al.add(newPerson("abc1"));

                   al.add(newPerson("abc2"));

                   al.add(newPerson("abc3"));

ArrayList<Student> al1 = newArrayList<Student>();

                   al1.add(newStudent("abc--1"));

                   al1.add(newStudent("abc--2"));

                   al1.add(newStudent("abc--3"));

                   printColl(al1);printColl(al)

}

         publicstatic void printColl(Collection<? extends Person> al)

         {

                   Iterator<?extends Person> it = al.iterator();

                   while(it.hasNext())

                   {

                            System.out.println(it.next().getName());

                   }

         };


 

 

Map概述

Map集合:该集合存储键值对,一对一对的存储,而且保证建的唯一性。

1、  添加

a)        put(K key,V value);

b)        putAll(Map<? extendsK,?extends V> m);

2、  删除

a)        clear();

b)        remove(Object key);

3、  判断

a)        containsValue(Object value);

b)        containsKey(Object key);

c)        isEmpty();

4、  获取

a)        get(Object key);

b)        size();

c)        values();//获取map集合中所有的值,并返回Collection对象。

d)        entrySet();

e)        keyset();

 

Map|--Hashtable

         |--HashMap

         |--TreeMap

Map子类对象特点

Hashtable:的底层是哈希表数据结构,不可以存入nullnull值,该集合是线程同步的。

HashMap:的底层是哈希表数据结构,允许使用nullnull值,该集合是不同步的。jdk1.2开始。效率高。其他功能与Hashtable相同。

TreeMap:底层是二叉树结构,线程不同步,可以用于给Map集合中的键进行排序。

Map的共性方法

可以通过get方法的返回值来判断一个键是否存在,通过返回null来判断。

 

在添加元素时,如果出现添加相同的键值,那么后添加的值会覆盖原有键值对应的值。

Map-keySet

Set<K> keyset:Map中所有的键存入到Set集合。因为Set具备迭代器,所以可以迭代方式取出所有的键,再根据get方法获取每一个键对应的值。

 

示例:

import java.util.*;

publicclassMapDemo2 {

   publicstaticvoid main(String[] args) { 

      Map<String,String>map=newHashMap<String,String>();

      map.put("02","zhangsan2");

      map.put("3", "zhangsan3");

      map.put("01", "zhangsan1");

      map.put("04", "zhangsan4"); 

//先获取map集合的所有键的Set集合,keySet(); 

      Set<String>keySet=map.keySet();

//有了Set集合。就可以获取其迭代器。

      Iterator<String>it=keySet.iterator();

      while(it.hasNext()){

         Stringkey=it.next();

//有了键可以通过map集合的get方法获取其对应的值。

         Stringvalue=map.get(key);

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

      }

   }

}


 

 

 

Map集合的取出原理:将map集合转成set集合。在通过迭代器取出。

Map-entrySet

2Set<Map.Entry<k,v>>entrySet:将map集合中的映射关系存入到了set集合中,

                                     而这个关系的数据类型就是:Map.Entry

 

                                     Entry其实就是Map中的一个static内部接口。

                                     为什么要定义在内部呢?

                                     因为只有有了Map集合,有了键值对,才会有键值的映射关系。

                                     关系属于Map集合中的一个内部事物。

                                     而且该事物在直接访问Map集合中的元素。

 

示例:

import java.util.*;

publicclassMapDemo2 {

   publicstaticvoid main(String[] args) { 

      Map<String,String>map=newHashMap<String,String>();

      map.put("02","zhangsan2");

      map.put("3", "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();

      while(it.hasNext()){

         Map.Entry<String,String> me=it.next();

         Stringkey=me.getKey();

         Stringvalue=me.getValue();

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

      }

   }

}


 

 

注意:一般和Hash…(哈希表)有关的集合在其存放的对象的类里一般要覆写hashCodeequals方法。

         一般和Tree…(二叉树)有关的集合,在其存放的对象的类里一般要继承Comparable并覆写compareTo方法。或写个比较,在用到时,创建集合对象时传入构造方法中。

 

扩展题:

捷答一:

/*

map扩展知识。

map集合被使用是因为具备映射关系。

"yureban"   Student("01" "zhangsan");

"yureban"Student("02" "lisi");

"jiuyeban""01" "wangwu";

"jiuyeban""02" "zhaoliu";

一个学校有多个教室。每一个教室都有名称。

*/

import java.util.*;

class  MapDemo31

{

   publicstaticvoid main(String[] args) 

   {     

      HashMap<String,HashMap<String,String>>czbk = newHashMap<String,HashMap<String,String>>();

      HashMap<String,String>yure = newHashMap<String,String>();

      HashMap<String,String>jiuye = newHashMap<String,String>();

      czbk.put("yureban",yure);

      czbk.put("jiuyeban",jiuye);

      yure.put("01","zhagnsan");

      yure.put("02","lisi");

      jiuye.put("01","zhaoliu");

      jiuye.put("02","wangwu");

      //遍历czbk集合。获取所有的教室。

      Iterator<String>it = czbk.keySet().iterator();

      while(it.hasNext())

      {

         StringroomName = it.next();

         HashMap<String,String>room = czbk.get(roomName);

         

         System.out.println(roomName);

         getStudentInfo(room);

      }     

      getStudentInfo(jiuye);

      getStudentInfo(yure);    

   }

   publicstaticvoidgetStudentInfo(HashMap<String,String> roomMap)

   {

      Iterator<String>it = roomMap.keySet().iterator();

      while(it.hasNext())

      {

         Stringid = it.next();

         Stringname = roomMap.get(id);

         System.out.println(id+":"+name);

      }

   }

}


 

 

 

 

 

解答二:

import java.util.*;

class Student1{

   private String id;

   private String name;

   Student1(Stringid,String name){

      this.name=name;

      this.id=id; 

   }

   public String toString(){

      returnid+"...."+name;

   }

}

publicclassMapDemo3 {

   publicstaticvoid demo() {

      HashMap<String,List<Student1>>czbk=newHashMap<String,List<Student1>>();

      List<Student1>reyu=newArrayList<Student1>();

      List<Student1>jiuye=newArrayList<Student1>();

      czbk.put("yureban",reyu);

      czbk.put("jiuyeban",jiuye);

      reyu.add(new Student1("01","zhangsan"));

      reyu.add(new Student1("02","lisi"));

      jiuye.add(new Student1("01","zhaoliu"));

      jiuye.add(new Student1("02","wangwu"));

      Iterator<String>it=czbk.keySet().iterator();

      while(it.hasNext()){

         StringroomName=it.next();

         List<Student1>room=czbk.get(roomName);

         getInfos(room);

      }  

   }

   privatestaticvoidgetInfos(List<Student1> room) {

      Iterator<Student1>it=room.iterator();

      while(it.hasNext()){

         Student1s=it.next();

         System.out.println(s);//此处打印student的对象,打印的是对象的地址,因为打印地址要调用toString方法,所以上面覆写了toString这里写s与写s.toString 一样。

      }     

   }

   publicstaticvoid main(String args[]){

      demo();

   }

}


 

 

什么时候用Map集合呢?

当数据之间存在着映射关系时就要先想Map集合。

Map集合被使用是因为其具备映射关系。

------- android培训java培训、期待与您交流! ----------详细请查看:http://edu.csdn.net 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值