Object类与包装类
in Java with 0 comment

Object类与包装类

in Java with 0 comment

Object类的使用

概念

equals()

概念

    public boolean equals(Object obj) {
        return (this == obj);
    }

举例

public class ObjectTest {
	public static void main(String[] args) {
		// 基本数据类型 ==
		int a = 10;
		int b = 10;
		System.out.println("int类型比较:" + (a == b));// true
		// Char类型
		char c1 = 65;
		char c2 = 'A';
		System.out.println("char类型比较" + (c1 == c2));// true

		// 基本数据类型自动提升
		int c = 65;
		System.out.println("char与int比较:" + (c == c1));// true
		System.out.println("char与int比较:" + (c == c2));// true
		float f1 = 65.0f;
		System.out.println("int与float比较:" + (c == f1));// true
		// 引用数据类型==
		Object object1 = new Object();
		Object object2 = new Object();
		System.out.println(object1 == object2);// false
		String s1 = new String("A");
		String s2 = new String("A");
		System.out.println(s1 == s2);// false
		System.out.println("****************");
		// equals
		System.out.println(object1.equals(object2));// true
		System.out.println(s1.equals(s2));// false
		// 通过以上引用数据类型发现:普通类中没有重写equals方法,导致使用object类中的
		// equals方法比较的,相当与==。而特殊的date、string类,都重写了equals方法,所以使用
		// 的比较都是内容的比较
		
	}
}

20200817094602

自定义equals()

通常情况下,我们自定义使用equals()方法的话,一般也是想比较两者的内容,而不是地址值。一般的我们是去比较类中的全部/部分属性内容是否一致

举例

定义Person类,属性nameageid

public class Person {
	String name;
	int age;
	int id = 1001;// 身份证号
	
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public void eat() {
		System.out.println("人吃饭");
	}

	public void walk() {
		System.out.println("人说话");
	}

	@Override
	public boolean equals(Object anObject) {
		// 判断两个是否是同一对象
		if (this == anObject) {
			return true;
		}
		// 判断是否是Person类
		if (anObject instanceof Person) {
			// 强转成Person
			Person p = (Person) anObject;
			if (this.age == p.age && this.name.equals(p.getName())) {
				return true;
			}
		}

		// 判断
		return false;
	}
}

测试

		// 重写equals
		System.out.println("****************");
		Person p1 = new Person("wr", 18);
		Person p2 = new Person("wr", 18);
		System.out.println(p1.equals(p2));

20200817094924

自动生成equals()

自己编写的equals()类可能存在一些问题,我们可以使用编辑器自带的生成工具。
shift+alt+sGenerate hashCode() and equals()

20200817095154

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Person other = (Person) obj;
		if (age != other.age)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

equals()练习

编写Order类,有int类型的orderId,String类型的orderName,相应的gettersetter方法,两个参数的构造器,重写父类的equals()方法,并测试判断类中的两个对象是否相等。

package com.eachwang.www.exer1;

import org.junit.Test;

public class Order {
	private int orderId;
	private String orderName;

	public Order() {
		super();
	}
//
//	public Order(int orderId, String orderName) {
//		super();
//		this.orderId = orderId;
//		this.orderName = orderName;
//	}

	public int getOrderId() {
		return orderId;
	}

	public void setOrderId(int orderId) {
		this.orderId = orderId;
	}

	public String getOrderName() {
		return orderName;
	}

	public void setOrderName(String orderName) {
		this.orderName = orderName;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj) {
			return true;
		}
		if (obj == null) {
			return false;
		}		if (getClass() != obj.getClass()) {
			return false;
		}
		Order od = (Order) obj;
		if (this.orderId != od.orderId) {
			return false;
		}
		if (this.orderName == null) {
			if (od.orderName != null) {
				return false;
			}
		} else if (!this.orderName.equals(od.orderName)) {
			return false;
		}

		return true;
	}

	// 测试
	@Test
	public void Test() {
//		测试类只能有一个构造方法
//		Order o1 = new Order(1, "零食");
//		Order o2 = new Order(2, "零食");
//		Order o3 = new Order(3, "日常用品");
//		Order o4 = new Order(3, "杂货");
//		Order o5 = new Order(3, "杂货");
		Order o1 = new Order();
		o1.orderId = 1;
		o1.orderName = "零食";

		Order o2 = new Order();
		o2.orderId = 2;
		o2.orderName = "零食";

		Order o3 = new Order();
		o3.orderId = 3;
		o3.orderName = "日常用品";

		Order o4 = new Order();
		o4.orderId = 3;
		o4.orderName = "杂货";

		Order o5 = new Order();
		o5.orderId = 3;
		o5.orderName = "杂货";
		System.out.println("ordid不一样name一样:" + (o1.equals(o2)));
		System.out.println("ordid不一样name不一样:" + (o1.equals(o3)));
		System.out.println("ordid一样name不一样:" + (o3.equals(o4)));
		System.out.println("ordid一样name一样:" + (o4.equals(o5)));

	}
}

20200817101344

面试题

  1. == 和 equals()方法的区别
    • ==
      • ==是运算符。
      • 使用在基本数据类型和引用数据类型中。
      • 基本数据类型:比较的是两个数值的是否相同。
      • 引用数据类型:比较的是两个类的地址值是否相同。两个引用是否指向同一个对象。
    • equals
      • equals()是方法
      • 使用在引用数据类型中。
      • Object类中的equals()方法,相当与==;特殊的,String、Date、File、包装类等都重写了equals()方法,所以比较的是对象中的内容。
    public boolean equals(Object obj) {
        return (this == obj);
    }

toString()方法

  1. toString()方式java.lang.Object类中定义的方法。 1. 输出一个对象的引用时,实际上就是调用的当前对象的toString()方法
  2. Object类中toString()类的定义:
public String toString() { 
    return getClass().getName() + "@" + Integer.toHexString(hashCode()); 
    }
  1. 特殊的,像Date、File、String、包装类等都重写了toString()方法,所以在调用对象的toString()方法的时候,返回“实体内容”信息
  2. 重写toString()方法
    • shift+alt+sGenerate toString()
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", id=" + id + "]";
	}

JUnit单元测试

步骤:

  1. 导包:Junit 4
  2. 创建Java类,进行单元测试
    1. Java类要求:此类是public的,提供公共无参的构造器
  3. 此类中声明单元测试方法
    1. 方法的权限是public
    2. 没有返回值
    3. 无形参
  4. 单元测试方法上面添加注解@Test,导包
import org.junit.Test;
public class JunitTest {
	int a = 10;

	public JunitTest() {

	}

	@Test
	public void test1() {
		System.out.println(111);
		// 调用属性
		System.out.println(a);
		// 调用方法
		show();
	}

	@Test
	public void test2() {
		System.out.println(4444);
	}

	private void show() {
		System.out.println("222");
	}
}

包装类的使用

概念

基本数据类型转包装类

  1. 通过构造器将基本数据类型转换成包装类
  2. 基本数据类型转包装类,构造器中可以传入相应的基本类型值、String类型值、可以自动提升的类型数值
  3. 注意Boolean类型,构造器传入String类型数据为truefalse都可以**(忽略大小写)**,传入其他值都为false
  4. Boolean类型String形参构造器中的详细源码:
    @Deprecated(since="9")
    public Boolean(String s) {
        this(parseBoolean(s));
    }
	
	public static boolean parseBoolean(String s) {
        return "true".equalsIgnoreCase(s);
    }

举例

	@Test
	public void test1() {
		// 基本数据类型转包装类
		int i1 = 10;
		Integer in1 = new Integer(i1);
		
		String s1 = "10";
		Integer in2 = new Integer(s1);

		System.out.println(in1.toString());// 20
		System.out.println(in2);// 10

		// 注意String类型必须是相应类型,不然会出现类型格式化错误
		// NumberFormatException
//		String s2 = "12a";
//		Integer in3 = new Integer(s2);
//		System.out.println(in3);

		float f1 = 12.2f;
		Float fl1 = new Float(f1);
		System.out.println(fl1.toString());// 12.2

		boolean bool = true;
		Boolean B = new Boolean(bool);
		System.out.println(B.toString());// true
		// 注意Boolean类型
		String str1 = "true";
		String str2 = "TrUe";
		String str3 = "truea";
		System.out.println(new Boolean(str1));// true
		System.out.println(new Boolean(str2));// true
		System.out.println(new Boolean(str3));// false

	}

包装类转基本数据类型

  1. 通过包装类(XXX)调用xxxValue()方法,就可以转成基本数据类型
  2. 举例:
    1. Integer in1 ; in1.intValue();
    2. Boolean bool1 ; bool1.booleanValue();
    3. Float fl1; fl1.floatValue();
  3. 数据类型高的可以转换为低的数据类型,比如Flaot类型包装类可以转换成int、float、byte等
    1. Float fl1 ; fl1.floatValue();fl1.intValue();fl1.byteValue();

举例

	// 包装类转基本数据类型
	@Test
	public void test2() {
		Integer in1 = new Integer(10);
		int i1 = in1.intValue();
		System.out.println(i1);// 10
		
		Float fl1 = new Float(11.1f);
		float f1 = fl1.floatValue();
		System.out.println(f1);// 11.1
		//降级float降级到int
		fl1.intValue();
		
		
		Boolean bool = new Boolean("asdf");
		boolean b = bool.booleanValue();
		System.out.println(b);// false
	}

新特性:自动装箱与自动拆箱

  1. JDK5.0以后,可以实现不通过构造器的方式进行基本数据类型转包装类
  2. JDK5.0以后,可以实现不通过调用xxxValue()方法进行包装类转基本数据类型
  3. 自动装箱格式:包装类 变量名 = 基本数据类型
  4. 自动拆箱格式:基本数据类型 变量名 = 包装类对象名

举例

	@Test
	public void test3() {
		//自动装箱与自动拆箱
		//自动装箱
		int i1 = 10;
		Integer in1 = i1;
		System.out.println(in1.toString());//10
		
		//自动拆箱
		int i2 = in1;
		System.out.println(i2);//10
	}

基本数据类型\包装类转成String

  1. 方式1:通过连接符
    • String 名称 = 基本数据类型名 + ""
  2. 方式2:通过String.valueOf(xxx)方法

举例

	@Test
	public void test4() {
		// 基本数据类型\包装类转成String
		// 方式1:连接符
		int i1 = 10;
		String str1 = i1 + "";

		// 方式2:valueOf()方法
		Integer in1 = i1;
		String str2 = String.valueOf(in1);//调用的是形参Object
		String str3 = String.valueOf(i1);//调用的是形参int
		System.out.println(str2);// 10
		System.out.println(str3);// 10
		Boolean bool = true;
		System.out.println(String.valueOf(bool));//调用的是形参Object
	}

String类型转成基本数据类型\包装类

  1. 通过包装类的parseXXX()方法转成基本数据类型\包装类。

举例

	@Test
	public void test5() {
		// String类型转成基本数据类型\包装类
		String str1 = "ABC";
		String str2 = "123";
		String str3 = "123.3";
		String str4 = "True";

		// 转成int
		int i1 = Integer.parseInt(str2);// 123

		// 转成float
		float fl1 = Float.parseFloat(str3);// 123.3
		Float fl2 = Float.parseFloat(str3);// 123.3

		// 转成boolean
		boolean bool1 = Boolean.parseBoolean(str4);// true
		boolean bool2 = Boolean.parseBoolean(str1);// false

		System.out.println(i1);
		System.out.println(fl1);
		System.out.println(fl2);
		System.out.println(bool1);
		System.out.println(bool2);
	}

包装类面试题

面试题1

	@Test
	public void test1() {
		Object o1 = true ? new Integer(1) : new Float(2.0f);
		System.out.println(o1);//1.0
	}

这个题的注意点,编译过程中三元运算符会提升类型,会将Integer提升到Float

面试题2

	@Test
	public void test2() {
		Object o1;
		if (true) {
			o1 = new Integer(1);
		} else {
			o1 = new Float(2.0f);
		}
		System.out.println(o1);//1
	}

这个题无需考虑类型提升。

面试题3

	@Test
	public void test3() {
		Integer i1 = new Integer(1);
		Integer i2 = new Integer(1);
		System.out.println(i1 == i2);//false

		Integer ii1 = 1;
		Integer ii2 = 1;
		System.out.println(ii1 == ii2);//true

		Integer iii1 = 128;
		Integer iii2 = 128;
		System.out.println(iii1 == iii2);//false
	}
    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    int i = parseInt(integerCacheHighPropValue);
                    i = Math.max(i, 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);

            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }

Integer里面有一个静态内部类IntegerCache,是一个缓存类,将范围-128~127的所有数字放进了cache[]的静态数组(提高效率),如果通过自动装箱的方式发现数据是-128~127的,就直接调用,无需new;-128~127范围外的需要new出来。

练习题1

public class AchievementTest {
	public static void main(String[] args) {
		// 获取输入对象
		Scanner scanner = new Scanner(System.in);
		// 创建
		Vector<Object> vector = new Vector<Object>();
		// 成绩最大值
		int max = 0;
		// 遍历数据
		// 输入负数截止
		for (;;) {
			// 判断输入是否为负数
			System.out.print("请输入成绩:");
			int data = scanner.nextInt();
			if (data < 0) {
				break;
			} else if (data > 100) {
				System.out.println("数据有误,请重新输!");
				continue;
			}
			// 输入正确,获取最大值
			if (max < data) {
				max = data;
			}
			// 保存数据

			// jdk5.0之前,不能存放基本数据类型,需要转成包装类,多态;jdk5.0之后可以存放,自动装箱
			Integer in = data;
			vector.addElement(in);
		}
		// 遍历比较
		for (int i = 0; i < vector.size(); i++) {
			// jdk5.0之前,不能存放基本数据类型,需要转成包装类;jdk5.0之后可以存放
			Integer in = (Integer) vector.get(i);
			int is = in;
			int s = max - is;
			if (s <= 10) {
				System.out.println("成绩:" + in + ",优秀");
			} else if (s <= 20) {
				System.out.println("成绩:" + in + ",合格");
			} else if (s <= 30) {
				System.out.println("成绩:" + in + ",及格");
			} else {
				System.out.println("成绩:" + in + ",不及格");
			}
		}
	}
}