Java的高级特性
今天的任务:
 1、hashCode()方法作用介绍
 2、对象克隆
 3、比较器
 4、Class类

1、hashCode---》哈希码
 Map--》HashMap、Hashtable
 实际上每一个对象都有一个hashCode;

import java.util.*;
   class Person{
    private String name;
    public Person(String name){
     this.name=name;
     }
    public String toString(){
     return "姓名:"+this.name;
     }
    }
   public class Demo{
    public static void main(String args[]) throws Exception{
     Map m=new HashMap();
     m.put("张三",new Person("张三"));
     System.out.println(m.get("张三"));
     }
    }


 以上可以得到值,要是如下该则得不到:

import java.util.*;
   class Person{
    private String name;
    public Person(String name){
     this.name=name;
     }
    public String toString(){
     return "姓名:"+this.name;
     }
    }
   public class Demo{
    public static void main(String args[]) throws Exception{
     Map m=new HashMap();
     m.put(new Person("张三"),"张三");
     System.out.println(m.get(new Person("张三")));
     }
    }


  原因是:new 又开辟了一个空间,不是原来的张三这个对象了,所以找不到,如果改成如下,
   就可以了;
 

import java.util.*;
    class Person{
     private String name;
     public Person(String name){
      this.name=name;
      }
     public String toString(){
      return "姓名:"+this.name;
      }
     }
    public class Demo{
     public static void main(String args[]) throws Exception{
      Map m=new HashMap();
      Person p=new Person("张三");
      m.put(p,"张三");
      System.out.println(m.get(p));
      }
     }


   以上总结:因为Object对象中有个hashCode()函数,每个对象都返回一个特有的hashCode;

   这样理解:为什么我们创建对象就是new的时候总是能在内存中分到不同的地址?
       为什么不同的对象在创建是不会覆盖以前创建的其他的对象呢?
   原因:    Object类中有个hashCode方法,和equals方法;
     

2、对象的克隆
 
 要完成克隆的类:
  类必须实现Cloneable接口,表示可以克隆
  类必须覆写clone方法
 

import java.util.*;
    class Person implements Cloneable {
     String name;
     int age;
     public Person(String name,int age){
      this.name=name;
      this.age=age;
      }
     public String toString(){
      return "姓名:"+this.name+",年龄:"+this.age;
      }
     public Object clone() throws CloneNotSupportedException{
      return super.clone();
      }
     }
     
    public class Demo{
     public static void main(String args[]) throws Exception{
      Person p1=new Person("李丹",19);
      Person p2=(Person)p1.clone();
      p2.name="于静";
      p2.age=29;
      System.out.println(p1);
      System.out.println(p2);
      }
     }

3、比较器---Comparable:
 Arrays类专门用于数组排序的;
 可以对任意的数据类型排序;
 

import java.util.*;
   public class Demo{
    public static void main(String args[]) throws Exception{
     int[] a={1,9,8,90,66,44};
     Arrays.sort(a);
     for(int i=0;i<a.length;i++){
      System.out.println(a[i]);
      }
     }
    }


 对象的比较:

import java.util.*;
   class Person implements Comparable{
    private String name;
    private int age;
    private float score;
    public Person(String name,int age,float score){
     this.name=name;
     this.age=age;
     this.score=score;
     }
    public String toString(){
     return "姓名:"+this.name+",年龄:"+this.age+",成绩:"+this.score;
     }
    //覆写compareTo方法就是排序规则
    public int compareTo(Object obj){
     Person p=(Person)obj;
     if(p.score>this.score){
      return 1;
      }
     else if(p.score<this.score){
      return -1;
      }
     else{
      //如果成绩相等则判断年龄
      if(p.age>this.age){
      return 1;
      }
      else if(p.age<this.age){
       return -1;
       }
      else{
       return 0;
       }
      }
     }
    }
   public class Demo{
    public static void main(String args[]) throws Exception{
     Person p[]=new Person[5];
     p[0]=new Person("张三",20,96);
     p[1]=new Person("李四",19,96);
     p[2]=new Person("王五",19,97);
     p[3]=new Person("赵六",21,78);
     p[4]=new Person("孙七",20,80);
     Arrays.sort(p);
     for(int i=0;i<5;i++){
      System.out.println(p[i]);
      }
     }
    }

 比较器除了用在Arrays类的排序外还可以用在TreeSet上,实际上TreeSet也需要比较器支持;

import java.util.*;
   class Person implements Comparable{
    private String name;
    private int age;
    private float score;
    public Person(String name,int age,float score){
     this.name=name;
     this.age=age;
     this.score=score;
     }
    public String toString(){
     return "姓名:"+this.name+",年龄:"+this.age+",成绩:"+this.score;
     }
    //覆写compareTo方法就是排序规则
    public int compareTo(Object obj){
     Person p=(Person)obj;
     if(p.score>this.score){
      return 1;
      }
     else if(p.score<this.score){
      return -1;
      }
     else{
      //如果成绩相等则判断年龄
      if(p.age>this.age){
      return 1;
      }
      else if(p.age<this.age){
       return -1;
       }
      else{
       return 0;
       }
      }
     }
    }
   public class Demo{
    public static void main(String args[]) throws Exception{
     Set s=new TreeSet();
     s.add(new Person("张三",20,96));
     s.add(new Person("李四",19,96));
     s.add(new Person("王五",19,97));
     s.add(new Person("赵六",21,78));
     s.add(new Person("孙七",20,80));
     Iterator iter=s.iterator();
     while(iter.hasNext()){
      System.out.println(iter.next());
      }
     }
    }

4、Class类:
 类---》对象
 我们希望有对象能够知道其所属的类是哪个;
 通过对象找到所属类,这就是反射机制;

import java.util.*;
   class Person {
    private String name;
    private int age;
    private float score;
    public Person(String name,int age,float score){
     this.name=name;
     this.age=age;
     this.score=score;
     }
    public String toString(){
     return "姓名:"+this.name+",年龄:"+this.age+",成绩:"+this.score;
     }
    }
   public class Demo{
    public static void main(String args[]) throws Exception{
     Person p=new Person("lid",19,99);
     //通过对象得到类的名字
     System.out.println(p.getClass().getName());
     }
    }
  Class 类能动态的为类实例化: 
  Class类本身没有构造方法:
   import java.util.*;
   public class Demo{
    public static void main(String args[]) throws Exception{
     //通过代码验证
     List all =null;
     //all=new ArrayList();
     //根据字符串找到一个类
     Class c=Class.forName("java.util.ArrayList");
     //实例化
     all=(List)c.newInstance();
     all.add("A");
     all.add("B");
     all.add("C");
     System.out.println(all);
     }
    }


 总结出java中对象实例化的途径:
  (1)直接用new:代码比较直观,但是 程序会出现耦合度
  (2)程序出现了接口,如果一个接口的子类直接通过new实例化会造成程序耦合度,
   所以通过工厂进行解耦合操作;
  (3)对象的克隆,将对象拷贝一份,此方法需要在子类写clone方法
  (4)Class 类,通过Class类来实例化一个对象,通过字符串操作完成;

  关于Class 类只需要重点掌握实例化对象的操作;
   但是对于以下一种情况不适合
   通过Class 类实例化其实就是调用类的无参构造方法来实例化;
 

import java.util.*;
     class Person{
      private String name;
      private int age;
      public Person(){
       }
      public Person(String name,int age){
       this.name=name;
       this.age=age;
       }
      public String toString(){
       return "姓名:"+this.name+";年龄:"+this.age;
       }
      }
      
     public class Demo{
      public static void main(String args[]) throws Exception{
       
       Person p=(Person)Class.forName("Person").newInstance();
       
       System.out.println(p);
       }
      }


  
   这样修改就可以了:
  

import java.util.*;
     import java.lang.reflect.*;
     class Person{
      private String name;
      private int age;
      public Person(String name,int age){
       this.name=name;
       this.age=age;
       }
      public String toString(){
       return "姓名:"+this.name+";年龄:"+this.age;
       }
      }
      
     public class Demo{
      public static void main(String args[]) throws Exception{
       Person p=null;
       Class c1=Class.forName("Person");
       Object obj[]={"张三",new Integer(30)};
       Constructor c=c1.getConstructors()[0];
       p=(Person)c.newInstance(obj);
       System.out.println(p);
       }
      }