黑马程序员-学习日记9(集合框架 4 )

 

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

 

/*
//Map集合:该集合存储键值对,一对一对往里存,而且要保证键的唯一性。
 1 ,添加。
 put(K key,V value);
 putAll(Map<? extends K,? extends V> m);
 2 ,删除。
 clear();
 remove(Object key);
 3 ,判断。
 containsValus(Object value);
 containsKey(Object key);
 isEmpty();
 4 ,获取。
 get(Object key);
 size();
 valuse();
 entrySet();
 keySet();
 5 ,Map
 |--Hashtable:底层是哈希表数据结构,不可以存入null键null值,一般元老级的类都是线程同步安全的,用作键的对象必须实现hashCode方法和equals方法。JDK1.0
 |--HashMap:底层是哈希表数据结构,允许使用null值和null键,该集合是不同步的。JKD1.2  它们的同与不同。效率高,上边效率底。
 |--TreeMap:底层是二叉树数据结构,线程不同步,可以用于给Map集合中的键进行排序。
 和Set很像,其实Set底层就是使用了Map集合。
 MAP集合的取出原理:将map集合转成set集合,在通过迭代器取出。


 

import java.util.*;
class MapDemo{
 public static void main(String args[]){
  Map<String,String> map = new HashMap<String,String>();
  map.put("01","zhangsan1");
  map.put("02","zhangsan2");
  map.put("03","zhangsan3");
  System.out.println("containsKey:"+map.containsKey("02"));
  System.out.println("containsKey:"+map.containsKey("022"));
  //System.out.println("remove:"+map.remove("022"));//null;
  //System.out.println("remove:"+map.remove("02"));//true;返回的是键对应的值。
  System.out.println(map);
  System.out.println("get:"+map.get("01"));//我们也可用get方法来判断某一个键是否存在。因为返回null表不存在。
  System.out.println("get:"+map.get("013"));//返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。

 

 }
}

//map.put("04",null);System.out.println("04");
//map.put(null,"haha");System.out.println(map.get(null));
//HashMap中null是可以作为键存在的!!!!HashTable不可以,因为它不支持空值键。
//可以通过get方法的返回值来判断一个键是否存在,返回的不是不是
//Map中的 V put(K key,V value)返回值为原来该键所对应的值V,而add();方法返回值为布尔值。
import java.util.*;
class MapDemo{
 public static void main(String args[]){
  Map<String,String> map = new HashMap<String,String>();
  map.put("01","zhangsan1");
  map.put(null,"hahaa");
  map.put("04",null);
  System.out.println("get:"+map.get("013"));//返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
  System.out.println("get:"+map.get(null));//HashMap中null是可以作为键存在的!!!!
  System.out.println("get:"+map.get("04"));
  Collection<String> coll = map.values();
  System.out.println(coll);//打印没顺序,因为是hash结构的。
 }
}

// V put(K key, V value)   特殊方法。
//该方法当存入相同键时,新值会替换老值,而且会将该键对应的原来的值返回。
  //第一次存入时,没有值所以返回空。
  //当添加时,添加了相同的键,那么后添加的值会覆盖原有对应的值,并返回被覆盖的值。

  //get方法比较的单一,不能一下全取出,
import java.util.*;
class MapDemo{
 public static void main(String args[]){
  Map<String,String> map = new HashMap<String,String>();
  //该方法当存入相同值时,新值会替换老值,而且会将该键对应的原来的值返回。
  //第一次存入时,没有值所以返回空。
  //当添加时,添加了相同的键,那么后添加的值会覆盖原有对应的值,并返回被覆盖的值。
  System.out.println(map.put("01","zhangsan1"));
  System.out.println(map.put("01","wangwu"));
  map.put(null,"hahaa");
  map.put("04",null);
  System.out.println(map);
 }
}

 

//map接口没有迭代器
//map集合的两种取出方式:
//1 ,KeySet:将map中的所有的键存入到Set集合中。因为set具备迭代器,所以可以用迭代方式取出所有的键,在根据get方法,获取每一个键对应的值。
//2 ,Set<> entrySet:将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry
import java.util.*;
class MapDemo{
 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集合,keySet();
 Set<String> keySet = map.keySet();
 //有了Set集合,就可以获取其迭代器。
 Iterator<String> it = keySet.iterator();
 while(it.hasNext()){
  String key = it.next();
  //有了键可通过map集合的get方法获取其对应的值。
  String value = map.get(key);
  System.out.println("key:"+key+", value:"+value);
 }
 }

}

//第二种方式,
//Set<Map.Entry<k,v>> entrySet:将集合中的映射关系存入到set集合中,而这个关系的数据类型是:Map.Entry.
import java.util.*;
class MapDemo{
 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();
  while(it.hasNext()){
   Map.Entry<String,String> me = it.next();
   String key = me.getKey();
   String value = me.getValue();
   System.out.println(key+"..::.."+value);
  }
 }
}

//Map.Entry 其实Entry也是一个接口。从定义上看出它是Map接口中的一个内部接口,是静态的,因为可通过类名调用,且对外暴露的。
//接口上可以定义内部接口。
interface Map{
 public static interface Entry {//静态对外暴露的。
  public abstract Object getKey();
  public abstract Object getValue();
 }
}
//因HashMap实现了Map接口,可在HashMap中定义内部类实现Map.Entry。
class HashMap implements Map{
 class Haha implements Map.Entry {
  public  Object getKey(){}
  public  Object getValue(){}
 }
}

 


每一个学生都有对应的归属地,学生Student,地址String
学生属性:姓名,年龄。注意:姓名和年龄相同视为同一个
学生。保证学生的唯一性。
1 ,描述学生。
2 ,定义map容器,将学生作为键,地址作为值,存入。
3 ,获取map集合中的元素。


import java.util.*;
class Student implements Comparable<Student>{
 private String name;
 private int age;
 Student(String name,int age){
  this.name = name;
  this.age = age;
 }
 public int compareTo(Student s){
  int num = new Integer(this.age).compareTo(new Integer(s.age));
  if(num==0)
   return this.name.compareTo(s.name);
  return num;  
 }
 public int hashCode(){
  return name.hashCode()+age*34;
 }
 public boolean equals(Object obj){
  if(!(obj instanceof Student))
   throw new ClassCastException("类型不匹配");
  Student s =(Student)obj;
  return this.name.equals(s.name) && this.age==s.age;
 }
 public String getName(){
  return name;
 }
 public int getAge(){
  return age;
 }
 public String toString(){
  return name+"..::.."+age;
 }

}
//当里面出现同名的键时,会覆盖掉原来的内容。
class MapDemo{
 public static void main(String args[]){
  HashMap<Student,String> hm = new HashMap<Student,String>();
  hm.put(new Student("lisi1",21),"beijing");
  hm.put(new Student("lisi1",21),"tian jing");//当里面出现同名的键时,会覆盖掉原来的内容。
  hm.put(new Student("lisi2",22),"shanghai");
  hm.put(new Student("lisi3",23),"nanjing");
  hm.put(new Student("lisi4",24),"wuhan");
  //第一种取出方式 keySet
  //Iterator<Student> it = hm.keySet().Iterator();
  Set<Student> keySet = hm.keySet();
  Iterator<Student> it = keySet.iterator();
  while(it.hasNext()){
   Student stu = it.next();
   String addr = hm.get(stu);
   System.out.println(stu.getName()+".."+stu.getAge()+"..."+addr);
  }

  //第二种取出方式:
  Set<Map.Entry<Student,String>> entrySet = hm.entrySet();
  Iterator<Map.Entry<Student,String>> iter = entrySet.iterator();
  while(iter.hasNext()){
   Map.Entry<Student,String> me = iter.next();
   Student stu = me.getKey();
   String addr = me.getValue();
   System.out.println(stu.getName()+"...."+stu.getAge()+">>>>>>>"+addr);

  }
 }
}

需求:对学生对象的年龄进行升序排序。
因为数据是以键值对形式存在的。
所以要使用可以排序的Map集合。TreeMap.
//按学生的姓名排序。

import java.util.*;
class MapDemo{
 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("blisi3",23),"nnnnnnnanjing");//覆盖掉了每一个元素。
  tm.put(new Student("lisi1",21),"beijing");
  tm.put(new Student("lisi4",24),"wuhan");
  tm.put(new Student("alisi2",22),"shanghi");
  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);
  }  
 }
}
class Student implements Comparable<Student>{
 private String name;
 private int age;
 Student(String name,int age){
  this.name = name;
  this.age = age;
 }
 public int compareTo(Student s){
  int num = new Integer(this.age).compareTo(new Integer(s.age));
  if(num==0)
   return this.name.compareTo(s.name);
  return num;  
 }
 public int hashCode(){
  return name.hashCode()+age*34;
 }
 public boolean equals(Object obj){
  if(!(obj instanceof Student))
   throw new ClassCastException("类型不匹配");
   if(this==obj)
    return true;
  Student s =(Student)obj;
  return this.name.equals(s.name) && this.age==s.age;
 }
 public String getName(){
  return name;
 }
 public int getAge(){
  return age;
 }
 public String toString(){
  return name+"..::.."+age;
 }
}
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;
 }
}


//练习:"sdfbzxcvasdfxcvdf"获取该字符串中的字母出现的次数。
//希望打印结果:a(1)c(2)......通过结果发现:每一个字母都有对应的次数,说明字母和次数之间有映射关系,注意:当发现有映射关系时,可以选择map集合,因为map集合中存放的就是映射关系。
//什么时候使用Map集合?当数据之间存在这映射关系时,就要先想Map集合。
//思想:1 ,将字符串转换成字符数组,因为要对每一个字母进行操作。
//2 ,定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
//3 ,遍历字符数组,将每一个字母作为健去查map集合。如果返回null,将该字母和1存入到map集合中,如果返回不是null,说明该字母在map集合中已存在并有对应次数,那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到map集合中,覆盖掉原来健对应的健。
//4 ,将map集合中的数据变成指定的字符串形式返回。
//注意:泛型类里接收的都是引用数据类型,必须找到其对应的基本数据类型包装类,
//第一次用a字母作为键去找集合,那么集合没有a这个键,所以也没有对应的次数,返回null;如果为null,就将a字母和1存入集合,
//如果指定的键已经存在,说明有对应的次数,就将对应的次数取出,并自增后再重新存入集合。
import java.util.*;
class MapDemo{
 public static void main(String args[]){
  String s = charCount("aabfcdabcdefa");
  System.out.println(s);
 }
 public static String charCount(String str){
  char[] chs = str.toCharArray();
  TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
  int count = 0; //以下代码的优化。
  for(int x=0;x<chs.length;x++){
   Integer value = tm.get(chs[x]);//返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
   //if(!(chs[x]>='a' && chs[x]<='z' || chs[x]>='A' && chs[x]<='z'))
   // continue;
    if(value==null){
     tm.put(chs[x],1);
    }else{
     value = value + 1;
     tm.put(chs[x],value);
    } 
    //以上代码的优化。
    
    //if(value!=null)
    // count = value;
    // count++;
    // tm.put(chs[x],count);
    // count = 0;
  }
  //System.out.println(tm);
  StringBuilder sb = new StringBuilder();
  Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();
  Iterator<Map.Entry<Character,Integer>> i = entrySet.iterator();
  while(i.hasNext()){
   Map.Entry<Character,Integer> me = i.next();
   Character ch = me.getKey();
   Integer value = me.getValue();
   sb.append(ch+"("+value+")");
  }
  return sb.toString();//此处一定要写toString方法,因为sb为StringBuilder类型。
 }
}

 

 

import java.util.*;
class MapDemo{
 public static void main(String args[]){
  charCount("aabfcdabcdefa");
  //System.out.println(s);
 }
 public static String charCount(String str){
  char[] chs = str.toCharArray();
  TreeMap<Character,Integer> tm = new TreeMap<Character,Integer>();
  for(int x=0;x<chs.length;x++){
   Integer value = tm.get(chs[x]);//返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
    if(value==null){
     tm.put(chs[x],1);
    }else{
     value = value + 1;
     tm.put(chs[x],value);
    }  
  }
  //System.out.println(tm);
  StringBuilder sb = new StringBuilder();
  Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet();
  Iterator<Map.Entry<Character,Integer>> i = entrySet.iterator();
  while(i.hasNext()){
   Map.Entry<Character,Integer> me = i.next();
   Character ch = me.getKey();
   Integer value = me.getValue();
   System.out.print(ch+"("+value+")");
  }
  return null;//此处一定要写toString方法,因为sb为StringBuilder类型。
 }
}

 

//map扩展知识。
//map集合被使用是因为具备映射关系。
一个学校有多个教室,一个教室有多个学生。
"yureban" "01" "zhangsan"
"yureban" "02" "lisi"
"jiuyeban" "01" "wangwu"
"jiuyeban" "02" "zhaoliu"

import java.util.*;
class MapDemo{
 public static void main(String args[]){
  HashMap<String,HashMap<String,String>> czbk = new HashMap<String,HashMap<String,String>>();
  HashMap<String,String> yure = new HashMap<String,String>();
  HashMap<String,String> jiuye = new HashMap<String,String>();
  czbk.put("yureban",yure);
  czbk.put("jiuyeban",jiuye);

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

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

  Iterator<String> it = czbk.keySet().iterator();
  while(it.hasNext()){
   String roomName = it.next();
   HashMap<String,String> room = czbk.get(roomName);
   System.out.println(roomName);
   getStuInfo(room);
  }
  
  //getStuInfo(yure);
  
 }
 public static void getStuInfo(HashMap<String,String> roomMap){
  Iterator<String> it = roomMap.keySet().iterator();
  while(it.hasNext()){
   String id = it.next();
   String name = roomMap.get(id);
   System.out.println(id+"::"+name);
  }
 } 
}

*/

 

import java.util.*;
class MapDemo{
 public static void main(String args[]){
  method1();
 } 
 public static void getInfos(List<Student> list){
  Iterator<Student> it = list.iterator();
  while(it.hasNext()){
   Student s = it.next();
   System.out.println(s);
  }
 }
 public static void method1(){
  HashMap<String,List<Student>> czbk = new HashMap<String,List<Student>>();
  List<Student> yure = new ArrayList<Student>();
  List<Student> jiuye = new ArrayList<Student>();

  czbk.put("yureban",yure);
  czbk.put("jiuyie",yure);
  yure.add(new Student("01","zhangsan"));
  yure.add(new Student("04","wangwu"));
  yure.add(new Student("01","zhangsan"));
  yure.add(new Student("02","zhaoli"));

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

  while(it.hasNext()){
   String roomName = it.next();
   List<Student> room = czbk.get(roomName);
   System.out.println(roomName);
   getInfos(room);
  }

 }
}
class Student{
 private String id ;
 private String name;
 Student(String id,String name){
  this.id = id;
  this.name = name;
 }
 public String toString(){
  return id+":::"+name;
 }
}

 

 

 

 

 

 

 

 

import java.util.*;
//Arrays:用于操作数据的工具类,里面都是静态方法。
/*

类 Arrays
java.lang.Object
  java.util.Arrays

--------------------------------------------------------------------------------

public class Arraysextends Object此类包含用来操作数组(比如排序和搜索)的各种方法。此类还包含一个允许将数组作为列表来查看的静态工厂


asList:将数组变成list集合。

//把数据变集合有什么好处?
当定义了一个数组,但想要判断一个元素是否在数组中存在,需要遍历数组逐个判断(较麻烦),当把它就集合后,一个方法就
搞定。contains();

可以使用集合的思想和方法来操作数组中的元素。
数组是一个对象但它里的方法比较少,转成集合后,里的方法多。

 

注意,将数组变成集合,不可以使用集合的增删方法,因为数组
的长度是固定的。可用的方法有:
contains() get()  indexOf() subList()
如果你增删了,那么会发生UnsupportedOperationException,

*/

import java.util.*;

class CollectionsDemo3{
 public static void main(String args[]){
  method1();
 }
 public static void method1(){
  int[] arr = {2,4,5};
  //打印2,4,5
  sop(Arrays.toString(arr));
 }
 public static void method2(){
  String[] arr = {"abc","cc","kkkk"}; 
  //sop(arr.toString());
  //为什么字符串数组往里放能转成集合而int数组不行呢。
  List<String> list = Arrays.asList(arr);
  //sop("contains:"+list.contains("cc"));
  //list.add("qq");//UnsupportedOperationException
  sop(list);
  //int[] nums = {2,4,5};
  Integer[] nums = {2,4,5};
  //如果数组中的元素都是对象,那么变成集合时,数组中的
  //元素就直接转成集合中的元素,如果数组中的元素都是
  //基本数据类型,那么会将该数组作为集合中的元素存在。

  List<Integer> li = Arrays.asList(nums);
  //List<int[]> li = Arrays.asList(nums);//里面只有一个对象。
  sop(li);
 }
 public static boolean myContains(String[] arr,String key){
  for(int x=0;x<arr.length;x++){
   if(arr[x].equals(key)){
    return true;
   }
  }
  return false;
 }
 

 public static void sop(Object o){
  System.out.println(o);
 }
}

//集合变数组。
//Collection接口中的toArray方法。

 


//ArrayList有两种取出元素的方式,迭代和(循环get)
//Set只有一种取出元素的方式,就是迭代器。
//Enumeration 沉沦了,因为他里的方法名过长不易书写,现在
//Iterator写起来也比较费事,所以又出了一个高级for
//JDK1.5后,Collection又有了一个爹,Iterable.(可迭代的接口)
//Map接口没有继承这接口,因为它里没有迭代器,这个接口的
//出现其实就是将迭代方法(iterator)抽取出来了,这样提高了
//集合框架的扩展性,(实现这个接口允许对象成为foreach语句的目标。
//高级for循环:学的是格式:
//for(集合或数组中的数据类型 变量名 : 被遍历的集合(Collection)或者数组){

//}
//对集合进行遍历时,只能获取集合中元素但不能对集合进行操作。
//迭代器除了遍历,还可以进行remove集合中元素的动作。remove后集合中的内容变了,
//如果使用ListIterator还可以在遍历过程中对集合进行增删改查的动作。

//传统for和高级for的区别:
//高级for有一个局限性:必须有被遍历的目标,将Hello world 打印一百次
//建议在遍历数组时还是希望使用传统for,因为它有角标,可对角标使用操作。

// 凡是支持迭代器的,都支持高级for。
//如果集合没有指定里面所存储的对象的类型高级for中只能用Object接收。
//ArrayList a1 = new ArrayList();
//for(Object o : a1)

class CollectionsDemo4{
 public static void main(String args[]){
  ArrayList<String> a1 = new ArrayList<String>();
  a1.add("abc2");
  a1.add("abc3");
  a1.add("abc1");
  Iterator<String> it = a1.iterator();
  while(it.hasNext()){
   System.out.println(it.next());
  }
  //底层原理还是迭代器,升级减化书写。
  //s第一次指向了集合中的第一个元素,当遍历到第二个
  //元素时,s又指向了abc3
  
  for(String s : a1){
   System.out.println(s);
  }
  sop("==========================");
  //变量s第一次指向集合中的每一个元素,然后变量s的
  //指向又改成"kkk"了,但集合中的内容没变过,,所以
  //这种方式是有局限性的,它只能对集合中的元素进行
  //取出而不能做修改动作,迭代器至少还有一个remove方法
  //
  for(String s : a1){
   s = "kkk";
   sop(s);
  }
  sop("==========================");
  int[] arr = {2,3,4,1};
  for(int i : arr){
   //sop(i);
   sop("Hello world");
  }
  sop("==========================");
  HashMap<Integer,String> hm = new HashMap<Integer,String>();
  hm.put(1,"a");
  hm.put(2,"b");
  hm.put(3,"c");
  for (Map.Entry<Integer,String> s : hm.entrySet())  {
   sop(s.getKey()+"..."+s.getValue());
  }
  sop("==========================");
  for(Integer s : hm.keySet()){
   sop(s+"..."+hm.get(s));
  }

 }
 public static void sop(Object o){
  System.out.println(o);
 }
}

 

 


/*
JDK1.5版本出现的新特性。

class CollectionsDemo4{
 public static void main(String args[]){
  //show(3,4);
  //int[] arr = {3,4};
  //show(arr);
  //int arr1 = {2,3,4,5};
  //show(arr1);
  //show1(2,3);//该方法打印的是[I@de6ced;
  //show1(2,3);
  //show1();
  show2(",,,,",1,2,3,4);
 }
 public static void show(int a,int b){
  System.out.println(a+","+b);
 }
 public static void show(int a,int b,int c){//重载形式:四个值也是重载

 }
 //因为存储的数据类型都一致,没有必要搞这样多的重载,
 //可用数组作参数来接收,但,每次都需要创建一个数组,
 WSEIOSX //比较的麻烦,(虽少定义了多个方法,但是每次都要定义
 //一个数组,作为实际参数。
 public static void show(int[] arr){
  //这里面可以for循环取值或其它 。
 }
 //1.5新特殊:
 //可变参数,其实是上一种数据参数的简写形式,
 //不用第一次都手动的建立数组对象,只要将要操作的元素
 //作为参数传递即可,隐式的将这些参数封装成了数组。
 //以前我们是手动的建立数组往里面传,现在我们只要
 //往里面传元素就行了,封装数组的动作不需要你来作,
 //而是由JVM帮你完成的,更简化你的操作,就如同:
 //高级for循环,底层用的还是迭代器。

 //在使用时注意:可变参数一定要定义在参数列表的最后面。
 public static void show1(int...arr){
  System.out.println(arr);
  //System.out.println(arr.length);
 }
 public static void show2(String s,int...arr){
  System.out.println(s+" "+arr.length);
 }
}

*/

 

 

 

 

 

你可能感兴趣的:(黑马程序员-学习日记9(集合框架 4 ))