Java学习(十二)--常用类

Object

它是所有类的根父类

    1、所有引用类型中都有Object类声明的方法;

    2、所有类创建对象,都会调用它的无参构造

  •         当一个类被定义后,如果没有指定继承的父类,那么默认父类就是 Object 类

    3、它的变量可以指向任意类型的对象

  •         Java 允许把任何类型的对象赋给 Object 类型的变量
  •         多态引用

常用方法

1、getClass()

  •     getClass() 方法返回对象所属的类,是一个 Class 对象
  •      通过 Class 对象可以获取该类的各种信息,包括类名、父类以及它所实现接口的名字等

2、equals(Object obj)

只能判断引用类型,比较两个对象地址;

子类常重写该方法,用于判断内容是否相等; 例如:String,Integer,Date,File等;

重写equals()方法的基本原则

  •     重写equals方法的时候一般都需要同时重写hashCode方法。要保证:equals返回true的两个对象,它们的hashcode值必须相等;
  •     通常参与计算hashCode的对象的属性也应该参与到equals()中进行计算;

与==区别

  •         判断基本类型,则判断 值是否相等
  •         判断引用类型,则判断 地址是否相等; 判断是不是同一个对象
/*
Jdk 的源码 String 类的 equals 方法,是把 Object 的 equals 方法重写了,变成了比较两个字符串值是否相同

    public boolean equals(Object anObject) {
        if (this == anObject) {//如果是同一个对象
            return true; //返回 true
        }
        if (anObject instanceof String) {//判断类型
            String anotherString = (String)anObject;//向下转型
            int n = value.length;
            if (n == anotherString.value.length) {//如果长度相同
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {//然后一个一个的比较字符
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;//如果两个字符串的所有字符都相等,则返回 true
            }
        }
        return false;//如果比较的不是字符串,则直接返回 false
    }
*/


/*
Object 的 equals 方法默认就是比较对象地址是否相同,也就是判断两个对象是不是同一个对象.
public boolean equals(Object obj) {
    return (this == obj);
}
*/

/*
Integer的equals方法,判断两个值是否相同;

    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
*/


/*
自定义equals方法:
判断两个 Person 对象的内容是否相等,如果两个 Person 对象的各个属性值都一样,则返回 true,反之 false.
*/
    public boolean equals(Object obj) {
        if (this == Person) {//如果是同一个对象
            return true; //返回 true
        }
        if (obj instanceof Person) {//判断类型
            Person person = (Person)obj;//向下转型
            //判断对象属性值是否相同,若相同则返回true;
                this.name.equals(p.name) && this.age == p.age
                return true;//如果相同,则返回 true            
        }
        return false;//如果不是Person类,则返回 false
    }

3、hashcode()

重写hashCode()方法的基本原则:

  •     程序运行时,同一个对象多次调用hashCode()方法应该返回相同的值
  •     两个对象的equals()方法比较返回true时,这两个对象的hashCode()方法的返回值也应相等
  •     对象中用作equals()方法比较的Field,都应该用来计算hashCode值;

        如果两个对象的hashcode值不相等,这两个对象一定是不相等
            y=f(x)
                y1!=y2,得出x1!=x2
        如果两个对象的hashcode值相等,不能决定这两个对象不相等
            y=f(x)
                y1=y2,不能推出x1=x2
        所以,两个对象hashcode值相等时,还需要调用equals方法继续判断;

两个引用,如果指向的是相同的对象,则哈希值一定相同;

两个引用,如果指向不同的对象,则哈希值是不一样的;

哈希值主要根据地址号来的!,但不能完全将哈希值等价于地址。

4、toString()

  •     从Object继承的,默认返回   运行时类名+@hashcode的无符号十六进制形式;【哈希码(hashCode),每个 Java 对象都有哈希码属性,哈希码可以用来标识对象,提高对象在集合操作中的执行效率。
  •     子类往往重写toString方法,用于返回对象的属性信息的字符串;        打印对象或拼接对象时,都会自动调用该对象的toString形式.
  •     当直接输出一个对象时,toString方法会被默认的调用
/*Object的toString源码:
   
 public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

(1)getClass().getName() 类的全类名(包名+类名 )
(2)Integer.toHexString(hashCode()) 将对象的 hashCode 值转成 16 进制字符串
*/


		Object o = new Object();
		System.out.println(o); //java.lang.Object@14ae5a5

5、finalize方法

  •     当对象被回收时,系统自动调用该对象的finalize方法。 子类可以重写该方法,做一些释放资源的操作
  •     垃圾回收机制的调用;        由系统来决定(即有自己的GC算法);       也可以通过System.gc()主动触发垃圾回收机制
  •     什么时候被回收;        当某个对象没有任何引用时,则jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象;        在销毁该对象前,会先调用finalize方法。
  • 在实际开发中,几乎不会运用 finalize;

包装类

产生原因:

1、在程序中某些位置,例如(集合,泛型)等不能使用基本数据类型,因此需要把基本数据类型转换成对象类型

2、但是基本数据类型,又节省空间又计算速度快,所以保留基本数据类型

3、Java 为每个基本类型都提供了包装类,可以将基本数据类型转换为对象来处理,并使用相关方法;    注意:java可以直接处理基本数据类型

与数据类型之间的关系

Java 1.5 版本之前必须手动拆箱装箱,之后可以自动拆箱装箱
 

引用类型转换

  •     引用类型转换为​​Number​​​类型,先调用​​valueOf​​​,再调用​​toString​​
  •     引用类型转换为​​String​​​类型,先调用​​toString​​​,再调用​​valueOf​​

Integer类

public class WrapperExercise02 {
	public static void main(String[] args) {
		Integer i = new Integer(1);
		Integer j = new Integer(1);
		System.out.println(i == j); // False
		/*
		//1. 如果 i 在 IntegerCache.low(-128)~IntegerCache.high(127),就直接从数组返回
		//2. 如果不在 -128~127,就直接 new Integer(i)
		public static Integer valueOf(int i) {
			if (i >= IntegerCache.low && i <= IntegerCache.high)
					return IntegerCache.cache[i + (-IntegerCache.low)];
					return new Integer(i);
		}
		*/

		Integer m = 1; // 底层 Integer.valueOf(1); -> 阅读源码
		Integer n = 1;// 底层 Integer.valueOf(1);
		System.out.println(m == n); // T

		// 所以,这里主要是看范围 -128 ~ 127 就是直接返回,否则,就 new Integer(xx);
		Integer x = 128;// 底层 Integer.valueOf(1);
		Integer y = 128;// 底层 Integer.valueOf(1);
		System.out.println(x == y);// False

		Integer i1 = new Integer(127);
		Integer i2 = new Integer(127);
		System.out.println(i1 == i2);//F

		Integer i5 = 127;//底层 Integer.valueOf(127)
		Integer i6 = 127;//-128~127
		System.out.println(i5 == i6); //T

		Integer i11=127;
		int i12=127;
		//只要有基本数据类型,判断的是值是否相同
		System.out.println(i11==i12); //T

		Integer i13=128;
		int i14=128;
		System.out.println(i13==i14);//T
	}
}

Float类

Number类

其他应用

注意:只要“+”运算符的一个操作数是字符串,编译器就会将另一个操作数转换成字符串形式,所以应该谨慎地将其他数据类型与字符串相连,以免出现意想不到的结果。

1)valueOf()

valueOf() 方法将数据的内部格式转换为可读的形式。
它是一种静态方法,对于所有 Java 内置的类型,在字符串内被重载,以便每一种类型都能被转换成字符串。
valueOf() 方法还被类型 Object 重载,所以创建的任何形式类的对象也可被用作一个参数。

这里是它的几种形式:
static String valueOf(double num)
static String valueOf(long num)
static String valueOf(Object ob)
static String valueOf(char chars[])

与前面的讨论一样,调用 valueOf() 方法可以得到其他类型数据的字符串形式——例如在进行连接操作时。
对各种数据类型,可以直接调用这种方法得到合理的字符串形式。所有的简单类型数据转换成相应于它们的普通字符串形式。
任何传递给 valueOf() 方法的对象都将返回对象的 toString() 方法调用的结果。事实上,也可以通过直接调用 toString() 方法而得到相同的结果。

对大多数数组,valueOf() 方法返回一个相当晦涩的字符串,这说明它是一个某种类型的数组。然而对于字符数组,它创建一个包含了字符数组中的字符的字符串对象。valueOf() 方法有一种特定形式允许指定字符数组的一个子集。

它具有如下的一般形式:
static String valueOf(char chars[ ], int startIndex, int numChars)

这里 chars 是存放字符的数组,startIndex 是字符数组中期望得到的子字符串的首字符下标,numChars 指定子字符串的长度。

2)parse()
parseXxx(String) 这种形式,是指把字符串转换为数值型,其中 Xxx 对应不同的数据类型,然后转换为 Xxx 指定的类型,如 int 型和 float 型。

3)toString()
toString() 可以把一个引用类型转换为 String 字符串类型,是 sun 公司开发 Java 的时候为了方便所有类的字符串操作而特意加入的一个方法。


字符串类

String

Java 没有内置的字符串类型,而是在标准 Java 类库中提供了一个 String 类来创建和操作字符串;

字符串的字符使用Unicode字符编码,一个字符(不区分字符或汉字)占两个字节;

在 Java 中定义一个字符串最简单的方法是用双引号把它包围起来;

  •     用双引号括起来的一串字符实际上都是 String 对象;    如字符串“Hello”在编译后即成为 String 对象;

String 是 final 类

  •     不能被其他的类继承
  •     代表不可变的字符序列;        一个字符串对象一旦被分配,其内容是不可变;
  •      value 是一个 final 类型, 不可以修改(地址不可修改):即 value 不能指向新的地址,但是单个字符内容是可以变化;
String s1 = "hello";
s1 = "haha";
// 创建2个对象


String a = "hello" + "abc" ;
//创建1个对象
//常量相加,看的是池;



String a = "hello";
String b = "abc";
String c = a + b;
/*
解读:
创建3个对象
1、先创建一个 StringBuilder sb = new StringBuilder ();
2、执行sb.append("hello");
3、执行sb.append("abc"); (sb在堆中)
4、String c = sb.toString();
最后c指向堆中的对象(string) value[]->池中'helloabc'。

变量相加,是在堆中。

*/


//即一旦一个 String 对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁;
//因为它的不可变性,所以拼接字符串时候会产生很多无用的中间对象,如果频繁的进行这样的操作对性能有所影响。


原因:
在jdk8中,String的底层是一个char数组,在String类源码中,有一个成员变量value,它是一个char数组引用,指向了存储Sting对象内容的char数组,value引用使用了final修饰(新建了一个对象返回,避免了对原对象value数组的改变):

 private final char value[]; 用于存放字符串内容

final的修饰使得String类的实现逻辑不改变,而实现逻辑保证了String对象的底层value数组的不改变,从而实现了String对象的不可变;

创建对象

直接赋值:

  • 先查看常量池中是否有“hsp”数据空间;
  • 若有,直接指向;
  • 若没有,重新创建,然后指向;

调用构造器:

  • 首先在堆中创建空间,里面维护了value属性,指向常量池的hsp空间;
  • 若有,直接通过value指向;
  • 若没有,则创建;

常用方法

1、equals: 比较内容是否相同,区分大小写

2、equalsIgnoreCase: 忽略大小写的判断内容是否相等

3、length: 获取字符的个数,字符串的长度

4、indexOf: 获取字符在字符串对象中第一次出现的索引,索引从0开始,如果找不到,返回-1

5、lastIndexOf: 获取字符在字符串中最后一次出现的索引,索引从0开始,如果找不到,返回-1

6、substring: 截取指定范围的子串;

7、toUpperCase: 转换成大写

8、toLowerCase:转换成小写

9、concat: 拼接字符串

10、replace: 替换字符串中的字符

11、split: 分割字符串; 对于某些分割字符,我们需要转义;比如: | \\等

12、toCharArray: 转换成字符数组;

13、compareTo: 比较两个字符串的大小;如果前者大, 则返回正数;后者大,则返回负数;如果相等,返回0;

14、format: 格式字符串;占位符: %s 字符串; %c 字符; %d  整型;%.2f 浮点型。

public class Test000 {
	public static void main(String[] args) {
		// 1.toUpperCase 转换成大写
		String s = "heLLo";
		System.out.println(s.toUpperCase());// HELLO

		// 2.toLowerCase 转换成小写
		System.out.println(s.toLowerCase());// hello

		// 3.concat 拼接字符串
		String s1 = "宝玉";
		s1 = s1.concat("林黛玉").concat("薛宝钗").concat("together");
		System.out.println(s1);// 宝玉林黛玉薛宝钗 together

		// 4.replace 替换字符串中的字符
		s1 = "宝玉 and 林黛玉 林黛玉 林黛玉";
		// 在 s1 中,将宝玉 替换为jack
		// 解读: : s1.replace() 方法执行后,返回的结果是替换过的.
		// s1 没有任何影响
		String s11 = s1.replace("宝玉", "jack");
		System.out.println(s1);// 宝玉 and 林黛玉 林黛玉 林黛玉
		System.out.println(s11);// jack and 林黛玉 林黛玉 林黛玉

		// 5.split 分割字符串, 对于某些分割字符,我们需要 转义比如 |\\等
		String poem = "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
		// 解读::
		// 1. 以 , 为标准对 poem 进行分割 , 返回一个数组
		// 2. 在对字符串进行分割时,如果有特殊字符,需要加入 转义符 \
		String[] split = poem.split(",");
		System.out.println(split);
		for (int i = 0; i < split.length; i++) {
			System.out.println(split[i]);
		}
		poem = "E:\\aaa\\bbb";
		split = poem.split("\\\\");
		System.out.println("==分割后内容===");
		for (int i = 0; i < split.length; i++) {
			System.out.println(split[i]);
		}

		// 6.toCharArray 转换成字符数组
		s = "happy";
		char[] chs = s.toCharArray();
		for (int i = 0; i < chs.length; i++) {
			System.out.println(chs[i]);
		}
		
		// 7.compareTo 比较两个字符串的大小,如果前者大,则返回正数,后者大,则返回负数,如果相等,返回 0
		/*解读:
		(1) 如果长度相同,并且每个字符也相同,就返回 0
		(2) 如果长度相同或者不相同,但是在进行比较时,可以区分大小就返回
		 if (c1 != c2) {
		return c1 - c2;
		}
		(3) 如果前面的部分都相同,就返回 str1.len - str2.len
		*/
		String a = "jcck";// len = 3
		String b = "jack";// len = 4
		System.out.println(a.compareTo(b)); // 返回值是 'c' - 'a' = 2 的值

		// 8.format 格式字符串
		/* 占位符有:
		 * %s 字符串 %c 字符 %d 整型 %.2f 浮点型
		 */
		String name = "john";
		int age = 10;
		double score = 56.857;
		char gender = '男';
		// 将所有的信息都拼接在一个字符串.
		String info =
				"我的姓名是" + name + "年龄是" + age + ",成绩是" + score + "性别是" + gender + "。希望大家喜欢我!";
		System.out.println(info);
		// 解读:
		// 1. %s , %d , %.2f %c 称为占位符
		// 2. 这些占位符由后面变量来替换
		// 3. %s 表示后面由 字符串来替换
		// 4. %d 是整数来替换
		// 5. %.2f 表示使用小数来替换,替换后,只会保留小数点两位, 并且进行四舍五入的处理
		// 6. %c 使用 char 类型来替换
		String formatStr = "我的姓名是%s 年龄是%d,成绩是%.2f 性别是%c.希望大家喜欢我! ";
		String info2 = String.format(formatStr, name, age, score, gender);
		System.out.println("info2=" + info2);
	}
}

StringBuffer

// 定义一个空的字符串缓冲区,含有16个字符的容量
StringBuffer str1 = new StringBuffer();

// 定义一个含有10个字符容量的字符串缓冲区
StringBuffer str2 = new StringBuffer(10);

// 定义一个含有(16+4)的字符串缓冲区,"青春无悔"为4个字符
StringBuffer str3 = new StringBuffer("青春无悔");

/*
*输出字符串的容量大小
*capacity()方法返回字符串的容量大小
*/
System.out.println(str1.capacity());    // 输出 16
System.out.println(str2.capacity());    // 输出 10
System.out.println(str3.capacity());    // 输出 20

StringBuilder

可变的字符序列,提供一个与StringBuffer兼容的API,但不保证同步;

用于字符串缓冲区被单个线程使用的时候;

速度快;

直接父类 AbstractStringBuilder;

主要操作是append和insert方法,可重载这些方法,以接受任意类型的数据。

比较


System类

//3个成员变量的使用
//需求: 编写一个 Java 程序,使用本节介绍的 System 类实现从键盘输入字符并显示出来。 

import java.io.IOException;
public class Test06 {
    public static void main(String[] args) {
        System.out.println("请输入字符,按回车键结束输入:");
        int c;
        try {
            c = System.in.read();    // 读取输入的字符
            while(c != '\r') {    // 判断输入的字符是不是回车
                System.out.print((char) c);    // 输出字符
                c = System.in.read();
            }
        } catch(IOException e) {
            System.out.println(e.toString());
        } finally {
            System.err.println();
        }
    }
}


System.in.read() 语句读入一个字符,read() 方法是 InputStream 类拥有的方法。变量 c 必须用 int 类型而不能用 char 类型,否则会因为丢失精度而导致编译失败。

如果要正常输出汉字,需要把 System.in 声明为 InputStreamReader 类型的实例,最终在 try 语句块中的代码为:
InputStreamReader in = new InputStreamReader(System.in, "GB2312");
c = in.read();
while(c != '\r') {
    System.out.print((char) c);
    c = in.read();
}
如上述代码所示,语句 InputStreamReader in=new InputStreamReader(System.in,"GB2312") 声明一个新对象 in,它从 Reader 继承而来,此时就可以读入完整的 Unicode 码,显示正常的汉字。

// currentTimeMillis() 方法:用来显示当前时间距离1970-1-1的毫秒数;

//该方法显示时间不够直观,但是可以很方便地进行时间计算。

//例如,计算程序运行需要的时间就可以使用如下的代码:
public class System_currentTimeMillis {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        for(int i = 0;i < 100000000;i++) {
            int temp = 0;
        }
        long end = System.currentTimeMillis();
        long time = end - start;
        System.out.println("程序执行时间" + time + "秒");
    }
}

//上述代码中的变量 time 的值表示代码中 for 循环执行所需要的毫秒数,使用这种方法可以测试不同算法的程序的执行效率高低,也可以用于后期线程控制时的精确延时实现。
public class System_getProperty {
    public static void main(String[] args) {

        String jversion = System.getProperty("java.version");

        String oName = System.getProperty("os.name");

        String user = System.getProperty("user.name");

        System.out.println("Java 运行时环境版本:"+jversion);

        System.out.println("当前操作系统是:"+oName);

        System.out.println("当前用户是:"+user);
    }
}

运行该程序,输出的结果如下:
Java 运行时环境版本:1.6.0_26
当前操作系统是:Windows 7
当前用户是:Administrator

BigInteger 和 BigDecimal 类
 

BigInteger:适合保存比较大的整数;

BigDecimal:适合保存精度更高的浮点型(小数);

参考文档:Java中的BigInteger类与BigDecimal类_biginteger bigdecimal-CSDN博客

日期类

Date(日期)类、Calendar(日历)类、LocalDateTime类;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Test000 {
	public static void main(String[] args) throws ParseException {
		Date d1 = new Date(); // 获取当前系统时间
		System.out.println("当前日期=" + d1);// 当前日期=Wed Jan 10 11:16:09 CST 2024

		Date d2 = new Date(9234567); // 通过指定毫秒数得到时间
		System.out.println("d2=" + d2); // d2=Thu Jan 01 10:33:54 CST 1970

		// 1. 创建 SimpleDateFormat 对象,可以指定相应的格式
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy 年 MM 月 dd 日 hh:mm:ss E");
		String format = sdf.format(d1); // format:将日期转换成指定格式的字符串
		System.out.println("当前日期=" + format); // 当前日期=2024 年 01 月 10 日 11:16:09 星期三

		// 解读:
		// 1. 可以把一个格式化的 String 转成对应的 Date
		// 2. 得到 Date 仍然在输出时,还是按照国外的形式,如果希望指定格式输出,需要转换
		// 3. 在把 String -> Date , 使用的 sdf 格式需要和你给的 String 的格式一样,否则会抛出转换异常
		String s = "1996 年 01 月 01 日 10:20:30 星期一";
		Date parse = sdf.parse(s);
		System.out.println("parse=" + sdf.format(parse)); //parse=1996 年 01 月 01 日 10:20:30 星期一
		System.out.println("parse=" + parse); //parse=Mon Jan 01 10:20:30 CST 1996
	}
}
import java.time.Instant;
import java.util.Date;
	
	//1.通过 静态方法 now() 获取表示当前时间戳的对象
		Instant now = Instant.now();
		System.out.println(now); //2024-01-10T03:23:02.424Z
		//2. 通过 from 可以把 Instant 转成 Date
		Date date = Date.from(now); 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hahaha2221

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值