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);
}
}