毕向东之Map
/* Map集合:该集合存储键值对。一对一对往里存,而且要保证键的唯一性.(Collection集合是单个存的) 存在映射关系时就用Map集合。 共性方法: 1.添加 put(K key,V value);//如果添加相同的键,那么后添加的值会覆盖原有键对应的值, 并且put方法会返回被覆盖的值; 添加不相同的键时返回null. putAll(Map<? extends K,? extends V> m); 2.删除 clear() remove(Object key) 3.判断 containsValue(Object value) containsKey(Object key) isEmpty() 4.获取 get(Object key);//存在则返回对应值,不存在返回null size() values();//获取所有的值 Map集合的两种取出方式:返回类型都是Set 1.keySet:将map中所有的键存入到Set集合,因为Set具备迭代器。 所以可以用迭代方法取出所有的键,再根据get方法获取每一个键对应的值。 Map集合的取出原理:将Map集合转成Set集合,再通过迭代器取出。 2.entrySet:返回类型Set<Map.Entry<k,v>>,将Map集合中的映射关系存入了Set集合, 这个关系就是Map.Entry类型(Entry接口是Map接口中的静态接口) Map |--Hashtable:底层是哈希表数据结构,不可以存入null键和null值,该集合是线程同步的。 |--HashMap:底层是哈希表数据结构,可以存入null键和null值,该线程是不同步的。(哈希值排序) |--TreeMap:底层是二叉树数据结构,可以用于给map集合中的键进行排序。(自定义方式排序如TreeSet) */ import java.util.*; public class Test1 { public static void main(String[] args) { HashMap<Integer,String> map=new HashMap<Integer,String>(); map.put(1,"abc1"); System.out.println(map.put(2,"abc2"));//null map.put(3,"abc3"); System.out.println(map.containsKey(1)); System.out.println(map.containsValue("abc2")); System.out.println(map.get(1)); map.put(null, "abc4"); System.out.println(map.values()); System.out.println(map); //方法一:利用keySet方法取出键值 HashMap<String,String> map1=new HashMap<String,String>(); map1.put("01", "张山01"); map1.put("02", "张山02"); map1.put("03", "张山03"); map1.put("04", "张山04"); //先获取map1集合中的键的Set集合 Set<String> keySet=map1.keySet(); //再获取Set集合的迭代器 Iterator<String> it=keySet.iterator(); //就可以输出每个键 while(it.hasNext()){ String key=it.next(); System.out.println(key); //有了键就可以输出键对应的每个值 System.out.println(map1.get(key)); } //方法二:利用entrySet方法取出键值 HashMap<String,String> map2=new HashMap<String,String>(); map2.put("01", "王五01"); map2.put("02", "王五02"); map2.put("03", "王五03"); map2.put("04", "王五04"); Set<Map.Entry<String, String>>Entry=map2.entrySet();//返回Map.Entry类型 Iterator<Map.Entry<String, String>> it1=Entry.iterator(); while(it1.hasNext()){ Map.Entry<String,String> me=it1.next();//关系迭代器给关系对象 String key=me.getKey();//通过对象调用关系中的键值 String value=me.getValue(); System.out.println("Key:"+key+",Value:"+value); } } }
hashCode()和equals()的关系是这样的:
如果两个对象相等(equal),它们的hashcode一定相同;
如果两个对象有相同的hashcode,它们不一定相等(equal);
/*要求:学生对象的年龄和姓名相同为同一个键 */ import java.util.*; public class Test2 { public static void main(String[] args) { HashMap<Student,String> hm=new HashMap<Student,String>(); hm.put(new Student("张山",23),"上海"); hm.put(new Student("张山",23),"北京"); //Map:如果添加相同的键,那么后添加的值会覆盖原有键对应的值,下文的equals做为判断键的依据 hm.put(new Student("李四",24),"北京"); hm.put(new Student("王五",25),"长沙"); hm.put(new Student("小六",26),"永州"); //第一种取出方式: Set<Student> set=hm.keySet(); Iterator<Student> iter=set.iterator(); while(iter.hasNext()){ Student s=iter.next(); String value=hm.get(s); System.out.println(s.getName()+","+s.getAge()+","+value); } System.out.println(); //第二种取出方式: Set<Map.Entry<Student, String>> se=hm.entrySet(); Iterator<Map.Entry<Student, String>> it=se.iterator(); while(it.hasNext()){ Map.Entry<Student, String> me=it.next(); Student key=me.getKey(); String value=me.getValue(); System.out.println(key.getName()+","+key.getAge()+","+value); } } } //Students创建的对象太多时,也许会存到HashSet中、TreeSet中去,所以要方法重写 class Student implements Comparable<Student>{ private String name; private int age; public Student(String name,int age){ this.name=name; this.age=age; } public String getName(){ return name; } public int getAge(){ return age; } public String toString(){ return "name:"+name+",age:"+age; } public int hashCode(){//对象的hash值,name也是个对象 return name.hashCode()+age*34;//34是保证每个对象hash值的唯一性 }//重写hashCode和equals方法是为了改变当存到HashSet集合中去的时候元素重复的条件 public boolean equals(Object obj){ if(!(obj instanceof Student)) throw new ClassCastException("类型转换异常啦");//运行时异常不需要throws声明 Student s=(Student)obj; return this.name.endsWith(s.name) && this.age==s.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; } }
/*要求:对学生对象年龄进行升序排序 因为数据是以键值对形式存在的,所以要使用可以排序的Map集合TreeMap 调用了Test2中的Student类 */ import java.util.*; public class Test3 { public static void main(String[] args) { TreeMap<Student,String> tm=new TreeMap<Student,String>(); //TreeMap<Student,String> tm=new TreeMap<Student,String>(new Mycompare()); //用自定义比较器按照姓名比较 tm.put(new Student("张山",23),"上海"); tm.put(new Student("张山",23),"北京"); //Map:如果添加相同的键,那么后添加的值会覆盖原有键对应的值,下文的equals做为判断键的依据 //和Test2不同的是这个使用TreeMap按照Student类中的compareTo方法排序,而前者使用哈希值排序。 tm.put(new Student("王五",25),"长沙"); tm.put(new Student("李四",24),"北京"); tm.put(new Student("小六",26),"永州"); Set<Student> set=tm.keySet(); Iterator<Student> iter=set.iterator(); while(iter.hasNext()){ Student s=iter.next(); String value=tm.get(s); System.out.println(s+","+value); } System.out.println(); //方法二获取 Set<Map.Entry<Student, String>> setEntry=tm.entrySet(); Iterator<Map.Entry<Student, String>> it=setEntry.iterator(); while(it.hasNext()){ Map.Entry<Student, String> me=it.next();//关系对象=对象; Student s=me.getKey();//获取关系中的键 String str=me.getValue();//获取关系中的值 System.out.println(s+","+str); } } } class Mycompare 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; } } /*=================================== 常用工具类: 一.Collections(对list集合的操作)静态方法 1.SynchronizedList(List<T> list) :返回一个安全的List,list里面的所以方法都加锁成安全的 2.swap(List<T> list,int i,int j) :交换角标i、j的位置 3.shuffle(List<?> list) :对元素随机排列(洗牌) 4.sort(List<T> list) :按自然顺序排列 升序,但是T必须继承了Comparable 5.sort(List<T> list,Comparator<? super T> c) :Collections.sort(list,new LenComparator());按照指定比较器排序 6.max(list) :自然顺序的最大值 7.max(list,comparator) :按照指定的比较器找最大值 8.binarySearch(list,元素) :二分法查找 找不到时返回负的角标减一(找不到的这个元素插入有序集合的角标) 9.fill(list,"pp") :将list中的所有元素都替换成pp 10.replaceAll(list,oldval,newval) :替换旧的 11.reverse(list) :反转 12.reverseOrder() :返回一个逆字典顺序的比较器 13.reverseOrder(comparator) :返回一个指定比较器的逆序比较器 二、 Arrays 1.asList :将数组变成list集合 好处:可以使用集合的方法操作数组中的元素(contains get indexof subList),但是不能使用增删方法,会报不支持操作异常 注意:如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素 如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在 2.toString(arr[]) :将指定数组以字符串的形式输出 三、Collection接口中的toArray方法 1.toArray(new String[0]) :将集合转变成指定类型的数组 (大小刚好比较合适) 为什么要将集合转变成数组?:限制操作,不能增删 四、静态导入:StaticImport 不需要写类.静态方法()中的类名 import static java.util.Arrays.*; //导入的是Arrays中的所有类的静态成员,而不是导入类 注意:当类名重名时,需要指定具体的包名 当方法重名时,指定具备所属的对象或者类 五、System 系统信息 1.Properties getProperties();//获取系统属性信息 Properties是Map的子类,所以可以通过map的方法取出 六、Runtime 对运行的处理 不可以new对象 1、getRuntime() 返回当前应用程序运行时对象 七、Date 日期 1.DateFormat-->SimpleDateFormat 如:SimpleDateFormat sdf=new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss"); String time=sdf.format(new Date()); 用模式格式化指定Date对象 八、Calendar 日历 比Date方法多 1.Calendar c=Calendar.getInstance();//当前日期 c.get(Calendar.Year);获取年份 比Date方便 九、Math 1.round 四舍五入 2.math.ceil(16.34) 返回大于指定数据的最小整数 3.floor 返回小于指定数据的最大整数 */