Set、HashSet、TreeSet、Map、HashMap、TreeMap

http://blog.csdn.net/rock_ray/article/details/20997145

1  Set集合

1.1  Set集合概述

Set集合的元素是无序的,即存入的顺序和取出的顺序不一定是一致的。

Set集合中的元素不可以重复。

Set类是Collection的子类,所以Set集合的功能和Collection是一致的。

Set集合的取出方式只有一种:Iterator迭代器。

 

Set:元素是无序的(存入和取出的顺序不一定一致),元素不可以重复,保证了元素唯一性。

|--HashSet:哈希表结构,线程不同步。

|--TreeSet:二叉树结构,可以对Set集合中的元素进行排序。


1.2  HashSet集合

HashSet集合是Set集合的一种,所以具有Set集合的特点:元素无序且唯一。

HashSet是线程不同步的,无序、高效。

HashSet集合的数据结构是哈希表。

 

哈希表:

1,对集合元素对象中的关键字(特有数据),进行哈希算法的运算,得出一个具体的值,这个值成为哈希值。

2,哈希值就是这个元素的位置。

3,如果哈希值出现冲突,再去判断这个关键字对应的对象是否相同。如果对象相同,就不存储,因为元素重复。如果对象不同,就存储,在原来对象的哈希值基础 +1顺延。

4,存储哈希值的结构,我们称为哈希表。

5,既然哈希表是根据哈希值存储的,为了提高效率,最好保证对象的关键字是唯一的。

这样可以尽量少的判断关键字对应的对象是否相同,提高了哈希表的操作效率。

 

HashSet集合如何保证元素的唯一性?

      是通过集合元素的两个方法:hashcode()和equals()来完成。

      如果元素的HashCode值(哈希值)相同,才会判断equals是否为true。

      如果元素的HashCode值不同,就不会再调用equals()方法。

      碰到哈希表数据结构,就要想到hashcode()和equals(),比如HashSet、HashMap等。

 

注意:在HashSet集合中,对于判断元素是否已存在,以及删除等操作,依赖的方法是元素对象的hashcode()和equals()方法。

      想删除元素,或判断元素,必须先判断hashcode(),再判断equals(),这就是HashSet集合的特点。

      而在ArrayList集合中,判断元素是否已存在,只根据equals()方法。

 

HashSet集合代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2. class HashSetDemo2{  
  3.     public static void main(String[] args){  
  4.         HashSet hs = new HashSet();  
  5.         hs.add(new Person("a1",11));  
  6.         hs.add(new Person("a2",12));  
  7.         hs.add(new Person("a3",13));  
  8.         hs.add(new Person("a2",12)); //(a2,12)这个对象哈希地址值相同,再equals(),已有一个相同的对象  
  9.                                       //这个(a2,12)就没有存入集合。  
  10.         //sop("a1--:"+hs.contains(new Person("a1",11)));  
  11.           
  12.         Iterator it = hs.iterator();  
  13.         while(it.hasNext()){  
  14.             Person p = (Person)it.next();  
  15.             sop(p.getName()+"..."+p.getAge());  
  16.         }  
  17.     }  
  18.     public static void sop(Object obj){  
  19.         System.out.println(obj);  
  20.     }  
  21. }  
  22.   
  23. class Person{  
  24.     private String name;  
  25.     private int age;  
  26.     Person(String name,int age){  
  27.         this.name = name;  
  28.         this.age = age;  
  29.     }  
  30.     public String getName(){  
  31.         return name;  
  32.     }  
  33.     public int getAge(){  
  34.         return age;  
  35.     }  
  36.       
  37. /*  hashCode()方法定义哈希值,哈希地址值相同,再判断是否是同一个对象,此时才用的equals(), 
  38.     如果哈希地址值不同,就用不到equals()。 
  39.     String定义了hashCode(); age*23 是为了防止不同对象姓名哈希值和age的和恰巧相同, */  
  40.     public int hashCode(){  
  41.         return name.hashCode()+age*23;  
  42.     }  
  43.       
  44.     //自定义判断对象是否重复的规则  
  45.     public boolean equals(Object obj){  
  46.         if(!(obj instanceof Person))  
  47.             return false;  
  48.         Person p =(Person)obj;  
  49.         System.out.println(this.name+"...equals..."+p.name);  
  50.           
  51.         return this.name.equals(p.name) && this.age==p.age;  
  52.     }  
  53. }  

1.3  TreeSet集合

TreeSet集合的数据结构是二叉树。

TreeSet集合是Set集合的一种,同样有元素无序且唯一的特点。

TreeSet集合可以用来对Set集合中的元素进行排序。

 

TreeSet集合的代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2. class TreeSetDemo{  
  3.     public static void main(String[] args){  
  4.         TreeSet ts = new TreeSet();  
  5.         ts.add("cba");  
  6.         ts.add("abcd");  
  7.         ts.add("aaa");  
  8.         ts.add("bca");  //默认按照逐个字母的ASCII码值进行排序。  
  9.           
  10.         Iterator it = ts.iterator();  
  11.         while(it.hasNext()){  
  12.             sop(it.next());  
  13.         }  
  14.     }  
  15.     public static void sop(Object obj){  
  16.         System.out.println(obj);  
  17.     }  
  18. }  

1.4  TreeSet集合第一种排序方式:元素自身必备比较性

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

元素需要实现Comparable接口,然后覆盖comparaTo()方法。这样元素自身就具备了比较性。

返回-1,则当前元素小于比较元素;返回1,则当前元素大于比较元素;返回0,则相同。

不做修改的默认顺序,也叫做自然顺序。

 

TreeSet第一种排序方式的代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2.   
  3. class TreeSetDemo2{  
  4.     public static void main(String[] args){  
  5.         TreeSet ts = new TreeSet();  
  6.         ts.add(new Student("lisi02",22));  
  7.         ts.add(new Student("lisi007",20));  
  8.         ts.add(new Student("lisi09",19));  
  9.         ts.add(new Student("lisi01",19));  
  10.           
  11.         Iterator it = ts.iterator(); //迭代器遍历  
  12.         while(it.hasNext()){  
  13.             Student stu = (Student)it.next();  
  14.             sop(stu.getName()+"..."+stu.getAge());  
  15.         }  
  16.     }  
  17.     public static void sop(Object obj){  
  18.         System.out.println(obj);  
  19.     }  
  20. }  
  21.   
  22. class Student implements Comparable {  //该接口强制让学生具备比较性。  
  23.     private String name;  
  24.     private int age;  
  25.       
  26.     Student(String name,int age){  
  27.         this.name = name;  
  28.         this.age = age;  
  29.     }  
  30.        
  31.     //覆盖接口Comparable中的compareTo方法,让学生具备比较性  
  32.     public int compareTo(Object obj){  
  33.         if(!(obj instanceof Student))  
  34.             throw new RuntimeException("不是学生对象");  
  35.         Student s = (Student)obj;  
  36.           
  37.         System.out.println(this.name+"...compareTo..."+s.name);  
  38.         if(this.age>s.age)  
  39.             return 1;  
  40.         if(this.age==s.age)  
  41.           
  42.             //年龄相同时按姓名排序。String类实现了Comparable接口。  
  43.             return this.name.compareTo(s.name);   
  44.         return -1;  
  45.     }  
  46.     public String getName(){  
  47.         return name;  
  48.     }  
  49.     public int getAge(){  
  50.         return age;  
  51.     }  
  52. }  

1.5  TreeSet集合第二种排序方式:集合具备比较性

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

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

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

自定义的Comparator的子类,需要覆盖compare()方法,据此进行比较,然后将这个子类对象传递给TreeSet的构造函数,TreeSet集合就具备了比较性。

 

两种排序方式,Comparator比较器的方式比较好。

 

需求:将上一节代码TreeSetDemo2,从按照年龄排序改成按照姓名排序。

定义一个类,实现Comparator比较器接口,覆盖compare()方法。

注意区别:Comparable接口中是compareTo()方法;而Comparator接口中是compare()方法。

同样是根据return的值来判断顺序。

 

请看代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2.   
  3. class TreeSetDemo3{  
  4.     public static void main(String[] args){  
  5.         TreeSet ts = new TreeSet(new MyComparator());  //将比较器对象传递给TreeSet构造函数。  
  6.         ts.add(new Student("lisi02",22));  
  7.         ts.add(new Student("lisi007",20));  
  8.         ts.add(new Student("lisi09",19));  
  9.         ts.add(new Student("lisi01",19));  
  10.           
  11.         Iterator it = ts.iterator();  
  12.         while(it.hasNext()){  
  13.             Student stu = (Student)it.next();  
  14.             sop(stu.getName()+"..."+stu.getAge());  
  15.         }  
  16.     }  
  17.     public static void sop(Object obj){  
  18.         System.out.println(obj);  
  19.     }  
  20. }  
  21.   
  22. class Student implements Comparable {  //该接口强制让学生具备比较性:按年龄排序  
  23.     private String name;  
  24.     private int age;  
  25.       
  26.     Student(String name,int age){  
  27.         this.name = name;  
  28.         this.age = age;  
  29.     }  
  30.        
  31.     public int compareTo(Object obj){   //覆盖接口Comparable中的方法,进行比较  
  32.         if(!(obj instanceof Student))  
  33.             throw new RuntimeException("不是学生对象");  
  34.         Student s = (Student)obj;  
  35.           
  36.         System.out.println(this.name+"...compareTo..."+s.name);  
  37.         if(this.age>s.age)  
  38.             return 1;  
  39.         if(this.age==s.age)  
  40.             return this.name.compareTo(s.name); //年龄相同是按姓名排序。  
  41.                                                  //String类实现了Comparable接口。  
  42.         return -1;  
  43.     }  
  44.     public String getName(){  
  45.         return name;  
  46.     }  
  47.     public int getAge(){  
  48.         return age;  
  49.     }  
  50. }  
  51.   
  52. class MyComparator implements Comparator{   //比较器方法:实现Comparator接口,传递给TreeSet构造函数  
  53.     public int compare(Object o1,Object o2){  //从而使TreeSet集合具有比较性,按照姓名排序  
  54.         Student s1 = (Student)o1;  
  55.         Student s2 = (Student)o2;  
  56.           
  57.         return s1.getName().compareTo(s2.getName());  
  58.     }  
  59. }  

1.6  TreeSet小练习

需求:根据字符串的长度进行排序。

使用第二中排序方式:比较器Comparator。

 

字符串String类的比较方法compareTo()比较的是自然顺序,不是我们想要的。

所以使用Comparator比较器方式。

 

比较时可以使用Integer基本数据类型包装类,比较int类型的自然顺序。

 

代码和注释:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2.   
  3. class TreeSetTest{  
  4.     public static void main(String[] args){  
  5.         TreeSet ts = new TreeSet(new StrComparator());  //比较器传递给TreeSet构造函数。  
  6.           
  7.         ts.add("abcd");  
  8.         ts.add("cc");  
  9.         ts.add("cba");  
  10.         ts.add("aaa");  
  11.         ts.add("hahaha");  
  12.           
  13.         Iterator it = ts.iterator();  
  14.         while(it.hasNext()){  
  15.             System.out.println(it.next());  
  16.         }  
  17.     }  
  18. }  
  19.   
  20. class StrComparator implements Comparator{  
  21.     public int compare(Object o1,Object o2){  
  22.         String s1 = (String)o1;  
  23.         String s2 = (String)o2;  
  24.           
  25.         /* if(s1.length() < s2.length()) 
  26.             return -1; 
  27.         if(s1.length()==s2.length()) 
  28.             return 0; 
  29.         return 1; */  
  30.                              //基本数据类型包装类Integer的compareTo()方法,比较自然顺序。  
  31.         int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));  
  32.           
  33.         if(num==0//如果字符串长度相同,再比较自然顺序。  
  34.             return s1.compareTo(s2); //调用String类的compareTo方法,根据自然顺序比较。(ASCII码)  
  35.           
  36.         return num;  
  37.     }  
  38. }  

2  Map集合

2.1  Map集合概述

Map集合和Collection集合不同,Collection集合存储的是一个元素,一个一个的存。

Map集合存储的是键值对(键:key,值:value),一对一对的往里存,键和值有映射关系。

而且,要保证Map集合中“键”的唯一性。

 

Map(注意HashTable和HashMap的相同和不同)

HashTable:底层是哈希表数据结构,不可以存入null键和null值,该集合是线程同步的,(键和值不能为空,效率较低)。

HashMap:底层是哈希表数据结构,可以存入null键和null值,该集合是线程不同步的,(键和值可以为空,效率较高)。

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

 

2.2  Map集合共性方法:

1,添加。

      put(K key, V value):添加一个键值对,返回原来与“键”对应的“值”,没有则返回null。

      putAll(Map<? extends K, ? extends V> m):从指定映射中将所有映射关系复制到此映射中。

2,删除。

      clear():清空所有键值对。

      removed(Object key):如果存在指定键的键值对,移除此键值对,并返回Value值。若不存在指定键的键值对,返回null。

3,判断。

      containsValue(Object value):是否包含有值为value的键值对,有的话返回true。

      containsKey(Object key):是否包含有键为key的键值对,有的话返回true。

      isEmpty():判断集合是不是空的。

4,获取。

      get(Object key):根据“键”返回“值”。

      size():返回“键值对”的个数。

      values():返回一个Collection集合,此集合中存储的是当前Map集合中所有“值”。

 

Map集合共性方法的简单代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2.   
  3. class MapDemo{  
  4.     public static void main(String[] args){  
  5.         Map<String,String> map = new HashMap<String,String>();  //集合的多态  
  6.           
  7.     /*  添加元素 
  8.         put方法的返回值是,返回原来与“键”对应的“值”,没有则返回null。 
  9.         这三个put方法都是返回null。 */  
  10.         map.put("01","zhangsan");   
  11.         map.put("02","lisi");        
  12.         map.put("03","wangwu");  
  13.           
  14.           
  15.         System.out.println("containsKey: "+map.containsKey("022"));  //判断  
  16.         //System.out.println("remove: "+map.remove("02"));   //删除元素  
  17.           
  18.         System.out.println("get: "+map.get("02")); //获取,get()根据“键”返回“值”。  
  19.         //可以通过get()方法的返回值来判断一个键是否存在,通过返回null来判断。  
  20.           
  21.         //获取Map集合中所有的值。  
  22.         Collection<String> coll = map.values();  
  23.         System.out.println("coll: "+coll);  
  24.           
  25.         System.out.println("map: "+map);  
  26.     }  
  27. }  

2.3  Map集合的两种取出方式

Set<K>  keySet();

Set<Map.Entry<K,Y>> entrySet();

Map集合的取出原理:将Map集合转换成Set集合,再通过迭代器取出。

 

1,keySet:将Map集合中所有的“键”存入到Set集合,因为Set有迭代器。

      所以能使用迭代方式去除所有的“键”,再根据get方法,获取对应的“值”。

2,entrySet:将Map集合中的映射关系取出,这个映射关系就是Map.Entry类型,即“键值对”。

      那么Map.Entry获取到后,就可以通过Map.Entry中的getKey和getValue方法,获取映射关系中的“键”和“值”。

接口Map.Entry介绍:

      其实Entry也是一个借口,它是Map接口中的一个内部接口。

interface Map{

      public static interface Entry{  //子接口

            public abstract Object getKey();

            public abstract Object getValue();

      }

}

 

Map集合两种取出方式的代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2.   
  3. class MapDemo2{  
  4.     public static void main(String[] args){  
  5.         method_keySet();  
  6.         method_entrySet();  
  7.     }  
  8.       
  9.     public static void method_keySet(){  
  10.         Map<String,String> map = new HashMap<String,String>();  
  11.         map.put("02","zhangsan");  
  12.         map.put("03","lisi");  
  13.         map.put("01","wangwu");  
  14.           
  15.         //先获取Map集合的所有“键”的Set集合,keySet();  
  16.         Set<String> ks = map.keySet();  
  17.           
  18.         //有了Set集合,就可以获取其迭代器。  
  19.         Iterator<String> it = ks.iterator();  
  20.           
  21.         while(it.hasNext()){  
  22.             String key = it.next();  
  23.             String value = map.get(key); //有了“键”,可以通过Map集合的get方法取得对应的“值”  
  24.               
  25.             System.out.println("ketSet_Key: "+key+" ketSet_value: "+value);  
  26.         }  
  27.     }  
  28.       
  29.     public static void method_entrySet(){  
  30.         Map<String,String> map = new HashMap<String,String>();  
  31.         map.put("02","zhangsan");  
  32.         map.put("03","lisi");  
  33.         map.put("01","wangwu");  
  34.           
  35.     /*  将Map集合中的映射关系取出,存入到Set集合中。 
  36.         此entrySet()方法返回值类型是Map.Entry<String,String>。 */  
  37.         Set<Map.Entry<String,String>> en = map.entrySet();  
  38.           
  39.         Iterator<Map.Entry<String,String>> it = en.iterator();  
  40.           
  41.         //迭代器的next()方法返回类型与Iterator的元素类型一样。  
  42.         while(it.hasNext()){  
  43.             Map.Entry<String,String> me = it.next();  
  44.             String key = me.getKey();  
  45.             String value = me.getValue();  
  46.               
  47.             System.out.println("entrySet_Key: "+key+" entrySet_value: "+value);  
  48.         }  
  49.     }  
  50. }  

2.4  HashMap集合

底层是哈希表数据结构,可以存入null键和null值,该集合是线程不同步的,(键和值可以为空,效率较高)。

 

HashMap集合小练习:

需求:

      每一个学生对象都有都有对应的归属地(学生Student,地址String)。

      学生属性:姓名,年龄。注意:姓名和年龄相同的,视为同一个学生。

      保证学生的唯一性。

思路:

1,Student类描述学生。

2,定义一个Map容器,将学生作为“键”,地址作为“值”,存入。

3,获取Map集合中的键值对,再依次获取键和值。

代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2.   
  3. class HashMapTest{  
  4.     public static void main(String[] args){  
  5.         HashMap<Student,String> map = new HashMap<Student,String>();  
  6.         map.put(new Student("zhangsan",21),"Beijing");  
  7.         map.put(new Student("lisi",22),"Shanghai");  
  8.         map.put(new Student("wangwu",23),"Wuhan");  
  9.         map.put(new Student("wangwu",23),"Changsha");  
  10.           
  11.         //获取存储键值对的Set集合。  
  12.         Set<Map.Entry<Student,String>> s = map.entrySet();//迭代器  
  13.           
  14.         Iterator<Map.Entry<Student,String>> it = s.iterator();  
  15.           
  16.         while(it.hasNext()){  
  17.             Map.Entry<Student,String> me = it.next();  
  18.             Student key = me.getKey();  
  19.             String value = me.getValue();  
  20.               
  21.             System.out.println("学生姓名:"+key.getName()+" 学生年龄:"+key.getAge()+" 地址:"+value);  
  22.         }  
  23.     }  
  24. }  
  25.   
  26. class Student implements Comparable<Student> {  //实现Comparable接口,使Student具有比较性。  
  27.     public String name;  
  28.     public int age;  
  29.       
  30.     Student(String name,int age){  
  31.         this.name = name;  
  32.         this.age = age;  
  33.     }     
  34.     public String getName(){  
  35.         return name;  
  36.     }     
  37.     public int getAge(){  
  38.         return age;  
  39.     }     
  40.     public int hashCode(){      //hashCode()和equals()保证唯一性。保证“键”的唯一性。  
  41.         return name.hashCode()+age*23;  
  42.     }  
  43.     public boolean equals(Object obj) {  
  44.         if(!(obj instanceof Student))  
  45.             throw new ClassCastException("类型不匹配"); //ClassCastException 是 RuntimeException的子类,可以不处理。  
  46.         Student s = (Student)obj;  
  47.         return this.name.equals(s.name) && this.age==s.age;  
  48.     }  
  49.     public int compareTo(Student s){  //重写Comparable接口的compareTo()方法,定义比较性。  
  50.         int num = new Integer(this.age).compareTo(new Integer(s.age));  
  51.         if(num==0)  
  52.             return this.name.compareTo(s.name);  
  53.         return num;  
  54.     }  
  55. }  

2.5  TreeMap集合

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

 

TreeMap集合小练习:

需求:按照学生对象的姓名进行排序。

      因为数据是以“键-值”对的形式存在,所以要使用可以排序的Map集合:TreeMap。

      TreeMap集合的构造方法可以传递Comparator比较器,而HashMap不可以。

      集合构造方法传递Comparator比较器,可以使集合自身具备比较性。

 

代码:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2.   
  3. class TreeMapTest{  
  4.     public static void main(String[] args){  
  5.         TreeMap<Student,String>  tm = new TreeMap<Student,String>(new StuNameComparator());  
  6.         tm.put(new Student("zhangsan",22),"Beijing");  
  7.         tm.put(new Student("lisi",21),"Shanghai");  
  8.         tm.put(new Student("wangwu",23),"Wuhan");  
  9.         tm.put(new Student("wangwu",23),"Changsha");  
  10.           
  11.         Set<Map.Entry<Student,String>> en = tm.entrySet();  
  12.           
  13.         Iterator<Map.Entry<Student,String>> it = en.iterator(); //迭代器  
  14.           
  15.         while(it.hasNext()){  
  16.             Map.Entry<Student,String> me = it.next();  
  17.             Student key = me.getKey();  
  18.             String value = me.getValue();  
  19.               
  20.             System.out.println("学生姓名:"+key.getName()+" 学生年龄:"+key.getAge()+" 地址:"+value);  
  21.         }  
  22.     }  
  23. }  
  24.   
  25. class Student {  
  26.     public String name;  
  27.     public int age;  
  28.       
  29.     Student(String name,int age){  
  30.         this.name = name;  
  31.         this.age = age;  
  32.     }  
  33.       
  34.     public String getName(){  
  35.         return name;  
  36.     }  
  37.       
  38.     public int getAge(){  
  39.         return age;  
  40.     }  
  41.       
  42.     public int hashCode(){ //hashCode()和equals()保证唯一性。保证“键”的唯一性。  
  43.         return name.hashCode()+age*23;  
  44.     }  
  45.       
  46.     public boolean equals(Object obj) {  
  47.         if(!(obj instanceof Student))  
  48.             throw new ClassCastException("类型不匹配"); //ClassCastException 是 RuntimeException的子类,可以不处理。  
  49.         Student s = (Student)obj;  
  50.         return this.name.equals(s.name) && this.age==s.age;  
  51.     }  
  52.       
  53.     /* public int compareTo(Student s){  //重写Comparable接口的compareTo()方法,使集合的元素具备比较性。 
  54.         int num = new Integer(this.age).compareTo(new Integer(s.age)); 
  55.         if(num==0) 
  56.             return this.name.compareTo(s.name); 
  57.         return num; 
  58.     } */  
  59. }  
  60.   
  61. class StuNameComparator implements Comparator<Student> {  //实现Comparator比较器,使集合自身具备比较性。  
  62.     public int compare(Student s1,Student s2){  
  63.         int num = s1.getName().compareTo(s2.getName());  
  64.           
  65.         if(num == 0)  
  66.             return new Integer(s1.getAge()).compareTo(new Integer(s1.getAge()));  
  67.         return num;  
  68.     }  
  69. }  

2.6  TreeMap集合练习

需求:

      “sdfssdsdqwqewdfzzxcxc”获取该字符串中的字母出现的次数。

      希望打印结果:a(1)c(2)......

      通过结果发现,每一个字母都有对应的次数。

      说明字母和次数之间都有映射关系。

注意:当发现有映射关系时,可以选择Map集合,因为Map集合中存放的就是映射。当数据之间存在着映射关系时,就要先想到Map集合。

思路:

1,将字符串转换成字符数组,因为要对每一个字母进行操作。

2,定义一个Map集合,因为打印结果的字母有顺序,所以使用TreeMap集合。

3,遍历字符数组:

      将每一个字母作为“键”去查Map集合。

      如果返回null,就将该字母和数字1存入Map集合(字母是键,数字1是值)。

      如果返回不是null,则说明该字母在Map集合已经存在并有对应次数。

      那么就获取该次数并进行自增,然后将该字母和自增后的次数,存入Map集合。

4,将Map集合中的数据变成指定的字符串形式返回。

 

代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2.   
  3. class TreeMapTest2 {  
  4.     public static void main(String[] args){  
  5.         charCount("sdfssdsdqwqewdfzzxcxc");  
  6.     }  
  7.       
  8.     public static void charCount(String str){  
  9.         char[] chs = str.toCharArray();  
  10.           
  11.         //泛型中的是引用类型,所以要用基本数据类型包装类。  
  12.         TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();   
  13.           
  14.         for(int x=0;x<chs.length;x++){  
  15.             Integer value = tm.get(chs[x]); //Map集合的get方法,根据“键”返回“值”  
  16.               
  17.             if(value==null)  
  18.                 tm.put(chs[x],1);  
  19.             else{  
  20.                 value = value+1;  
  21.                 tm.put(chs[x],value);  
  22.             }  
  23.         }  
  24.         System.out.println(tm);  
  25.           
  26.         StringBuilder sb = new StringBuilder();  //利用缓冲区StringBuider,打结果。  
  27.           
  28.         Set<Map.Entry<Character,Integer>> en = tm.entrySet();  
  29.         Iterator<Map.Entry<Character,Integer>> it = en.iterator();  
  30.         while(it.hasNext()){  
  31.             Map.Entry<Character,Integer> me = it.next();  
  32.             Character ch = me.getKey();  
  33.             Integer in = me.getValue();  
  34.             sb.append(ch+"("+in+")");  
  35.         }  
  36.           
  37.         System.out.println(sb);  
  38.     }  
  39. }  

3. Map集合扩展知识:集合嵌套集合

集合嵌套集合,即集合的元素中包含集合。

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

"yureban"  "01"  "zhangsan"

"yureban"  "02"  "lisi"

"jiuyeban"  "01"  "wangwu"

"jiuyeban"  "02"  "zhaoliu"

 

代码示例:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import java.util.*;  
  2.   
  3. class MapDemo3{  
  4.     public static void main(String[] args){  
  5.         HashMap<String,String> yure = new HashMap<String,String>();  
  6.         yure.put("01","zhangsan");  
  7.         yure.put("02","lisi");  
  8.           
  9.         HashMap<String,String> jiuye = new HashMap<String,String>();  
  10.         jiuye.put("01","wangwu");  
  11.         jiuye.put("02","zhaoliu");  
  12.           
  13.         HashMap<String,HashMap<String,String>> czbk = new HashMap<String,HashMap<String,String>>();  
  14.         czbk.put("yureban",yure);  
  15.         czbk.put("jiuyeban",jiuye);  
  16.           
  17.         //getStudentInfo(jiuye);  
  18.         //getStudentInfo(yure);  
  19.           
  20.         //遍历czbk集合,获取所有的教室  
  21.         Iterator<String> it = czbk.keySet().iterator();  
  22.           
  23.         while(it.hasNext()){  
  24.             String key = it.next();  
  25.             HashMap<String,String> value = czbk.get(key);  
  26.               
  27.             getStudentInfo(value);  
  28.         }  
  29.           
  30.     }  
  31.       
  32.     public static void getStudentInfo(HashMap<String,String> roomMap){  
  33.         Iterator<String> it = roomMap.keySet().iterator();  
  34.           
  35.         while(it.hasNext()){  
  36.             String id = it.next();  
  37.             String name = roomMap.get(id);  
  38.               
  39.             System.out.println(id+":"+name);  
  40.         }  
  41.     }  
  42. }  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值