java零基础Ⅱ-- 4.常用类

java基础 专栏收录该内容
22 篇文章 1 订阅

连接视频



一、包装类

包装类的分类

  1. 针对八种基本数据类型相应的引用类型 – 包装类
  2. 有了类的特点,就可以调用类中的方法
基本数据类型包装类
booleanBoolean
charCharacter
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble

源码:

boolean --->Boolean

在这里插入图片描述

package java.lang;

public final class Boolean implements java.io.Serializable,
                                      Comparable<Boolean>
{...

char ---> Character

在这里插入图片描述

package java.lang;

public final
class Character implements java.io.Serializable, Comparable<Character> {

byte ---> Byte

在这里插入图片描述

package java.lang;

public final class Byte extends Number implements Comparable<Byte> {

short ---> Short

在这里插入图片描述

package java.lang;

public final class Short extends Number implements Comparable<Short> {

int ---> Integer

在这里插入图片描述

package java.lang;

public final class Integer extends Number implements Comparable<Integer> {

long ---> Long

在这里插入图片描述

package java.lang;

public final class Long extends Number implements Comparable<Long> {

float ---> Float

在这里插入图片描述

package java.lang;

public final class Float extends Number implements Comparable<Float> {

double ---> Double

在这里插入图片描述

package java.lang;

public final class Double extends Number implements Comparable<Double> {

在这里插入图片描述


包装类和基本数据的转换

演示 包装类 和 基本数据类型的相互转换,这里以 int 和 Integer演示。

1)jdk5 前的手动装箱和拆箱方式,装箱基本类型 --> 包装类型,反之,拆箱

2)jdk5 以后(含jdk5)的自动装箱和拆箱方式

3)自动装箱底层调用的是valueOf方法,比如:Integer.valueOf()

4)其它包装类的用法类似


演示

package com.zzpwdu.wrapper;

public class Integer01 {
    public static void main(String[] args) {
        //演示int <--> Integer 的装箱和拆箱
        //jdk5前是 手动装箱和拆箱
        //手动装箱 int --> Integer
        int n1 = 100;
        Integer integer = new Integer(n1);
        Integer integer1 = Integer.valueOf(n1);
        //手动拆箱
        // Integer --> int
        int i = integer.intValue();

        //jdk5后(包含),就可以自动装箱和自动拆箱
        int n2 = 200;
        //自动装箱 int --> Integer
         Integer integer2 = n2;//底层使用的是 Integer.valueOf(n2);
        //自动拆箱 Integer --> int
        int n3 = integer2;//底层仍然使用的是 integer2.intValue();
    }
}

测试题

下面代码是否正确:

Double d = 100d;//ok,自动装箱 Double.valueOf(100d); 
Float f = 1.5f;//ok,自动装箱 Float.valueOf(1.5f); 

如下两个题目输出结果相同吗?各是什么?

Object obj1 = true? new Integer(1) : new Double(2.0);//三元运算符【是一个整体】
System.out.println(obj1);//1.0 因为后面有Double类型
Object obj2;
if(true){
	obj2 = new Integer(1);
}else{
	obj2 = new Double(2.0);
}
System.out.println(obj2);//1 ,分别计算
public class WrapperException01 {
    public static void main(String[] args) {
        Double d = 100d;//ok,自动装箱 Double.valueOf(100d);
        Float f = 1.5f;//ok,自动装箱 Float.valueOf(1.5f);
        Object obj1 = true? new Integer(1) : new Double(2.0);//三元运算符【是一个整体】
        System.out.println(obj1);//1.0 因为后面有Double类型

        Object obj2;
        if(true){
            obj2 = new Integer(1);
        }else{
            obj2 = new Double(2.0);
        }
        System.out.println(obj2);//1 ,分别计算
    }
}
===========控制台输出=============
1.0
1

包装类型和String类型的相互转换

案例演示,以Integer 和 String 转换为例,其它类似:

// 包装类型 -------> String类型
Integer i = 100;
// 方式1
String s1 = i.toString();
// 方式2
String s2 = String.valueOf(i);
// 方式3
String s3 = i + "";
System.out.println(s3);
// String ------> 包装类
// 方式1
Integer j = new Integer(s1);
// 方式2
Integer j2 = Integer.valueOf(s2);
public class WrapperVSString {
    public static void main(String[] args) {
        //包装类(Integer) --> String
        Integer i = 100;//自动装箱
        //方式1
        String str1 = i + "";
        //方式2
        String str2 = i.toString();
        //方式3
        String str3 = String.valueOf(i);

        //String -> 包装类(Integer)
        String str4 = "1234";
        Integer i2 = Integer.parseInt(str4);//使用到自动装箱
        Integer i3 = new Integer(str4);//构造器

        System.out.println("ok~");
    }
}

Integer类和Character类的常用方法

Integer 类和 Character 有些常用的方法,我们一起来使用一下

System.out.println(Integer.MIN_VALUE);//返回最小值 -2147483648
System.out.println(Integer.MAX_VALUE);//返回最大值 2147483647

System.out.println(Character.isDigit('a'));//判断是不是数字 false
System.out.println(Character.isLetter('a'));//判断是不是字母 true
System.out.println(Character.isUpperCase('a'));//判断是不是大写 false
System.out.println(Character.isLowerCase('a'));//判断是不是小写 true

System.out.println(Character.isWhitespace('a'));//判断是不是开个 false
System.out.println(Character.toUpperCase('a'));//转成大写 A
System.out.println(Character.toLowerCase('A'));//转成小写 a

Integer类面试题1

看看下面代码,输出什么结果?为什么?

public void method1(){
	Integer i = new Integer(1);
	Integer j = new Integer(1);
	System.out.println(i == j);//false

	Integer m = 1;//底层是 Integer.valueOf(1)
	Integer n = 1;//底层是 Integer.valueOf(1)
	//所以,这里主要看范围 -128 ~ 127 就是直接返回
	/*
		源码:
		public static Integer valueOf(int i) {
	        if (i >= IntegerCache.low && i <= IntegerCache.high)//-128 到 127
	            return IntegerCache.cache[i + (-IntegerCache.low)];
	       	 return new Integer(i);
    	}
	*/
	System.out.println(m == n);//turn

	//所以,这里主要看范围 -128 ~ 127 就是直接返回
	//否则,就 new Integer(i);
	Integer x = 128;//底层是 Integer.valueOf(1)
	Integer y = 128;//底层是 Integer.valueOf(1)
	System.out.println(x == y);//false
}
public class WrapperException02 {
    public static void main(String[] args) {
        Integer i = new Integer(1);
        Integer j = new Integer(1);
        System.out.println(i == j);//false

        Integer m = 1;//底层是 Integer.valueOf(1)
        Integer n = 1;//底层是 Integer.valueOf(1)
        //所以,这里主要看范围 -128 ~ 127 就是直接返回
	    /*
		解读源码:
		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)//-128 到 127
                return IntegerCache.cache[i + (-IntegerCache.low)];
             return new Integer(i);
        }
	    */
        System.out.println(m == n);//turn

        //所以,这里主要看范围 -128 ~ 127 就是直接返回
        //否则,就 new Integer(i);
        Integer x = 128;//底层是 Integer.valueOf(1)
        Integer y = 128;//底层是 Integer.valueOf(1)
        System.out.println(x == y);//false
    }
}
===========控制台输出=============
false
true
false

Integer类面试题总结

看看下面代码,输出什么结果

// 实例一
Integer i1 = new Integer(127);
Integer i2 = new Integer(127);
System.out.println(i1 == i2);//false

// 实例二
Integer i3 = new Integer(128);
Integer i4 = new Integer(128);
System.out.println(i3 == i4);//false

// 实例三
Integer i5 = 127;//底层是 Integer.valueOf(127)
Integer i6 = 127;//-128~127
System.out.println(i5 == i6);//true

// 实例四
Integer i7 = 128;
Integer i8 = 128;
System.out.println(i7 == i8);//false

// 实例五
Integer i9 = 127;//底层是 Integer.valueOf(127)
Integer i10 = new Integer(127);
System.out.println(i9 == i10);//false

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

// 实例七
Integer i13 = 128;
int i14 = 128;
System.out.println(i13 == i14);//true
public class WrapperException03 {
    public static void main(String[] args) {
        // 实例一
        Integer i1 = new Integer(127);
        Integer i2 = new Integer(127);
        System.out.println(i1 == i2);//false

        // 实例二
        Integer i3 = new Integer(128);
        Integer i4 = new Integer(128);
        System.out.println(i3 == i4);//false

        // 实例三
        Integer i5 = 127;//底层是 Integer.valueOf(127)
        Integer i6 = 127;//-128~127
        System.out.println(i5 == i6);//true

        // 实例四
        Integer i7 = 128;
        Integer i8 = 128;
        System.out.println(i7 == i8);//false

        // 实例五
        Integer i9 = 127;//底层是 Integer.valueOf(127)
        Integer i10 = new Integer(127);
        System.out.println(i9 == i10);//false

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

        // 实例七
        Integer i13 = 128;
        int i14 = 128;
        System.out.println(i13 == i14);//true
    }
}
===========控制台输出=============
false
false
true
false
false
true
true



二、String类

String类的理解和创建对象

在这里插入图片描述

1)String 对象用于保存字符串,也就是一组字符序列

2)字符串常量对象是用双引号括起的字符序列。例如:“你好”,“12.97”,"boy"等

3)字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节

4)String类较常用构造器方法

  • String s1 = new String();
  • String s2 = new String(String original);
  • String s3 = new String(char[] a);
  • String s4 = new String(char[] a, int startIndex, int count);
  • String s5 = new String(byte[] b);
  • 说明
package com.zzpwdu.string_;

public class String01 {
    public static void main(String[] args) {
        //1.String 对象用于保存字符串,也就是一组字符序列
        //2."jack" 字符串常量,双引号括起的字符序列
        //3.字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占两个字节
        //4.String 类有很多构造器,构造器的重载
        // 常用的有 String s1 = new String();
        //String s2 = new String(String original);
        //String s3 = new String(char[] a);
        //String s4 = new String(char[] a, int startIndex, int count);
        //String s5 = new String(byte[] b);
        //5.String 类实例了接口 Serializable【String 可以串行化:可以在网络传输】
        //               接口 Comparable【String 对象可以比较大小】
        //6. String 是一个final 类,不能被其他类继承
        //7. String 有属性 private final char value[];用于存放字符串内容
        //8. 一定要注意:value 是一个final类型,不可修改(即:value不能指向新的地址,但是单个字符内容是可以变化的)
        String name = "jack";
        name = "tom";
        final char value[] = {'a','b','c'};
        char[] v2 = {'t','o','m'};
        value[0] = 'h';
        //value = v2;//错误 不可以修改 value地址
    }
}

创建String对象的两种方式

1)方式一:直接赋值 String s = “zzp”;

2)方式二:调用构造器 String s2 = new String(“zzp”);

1、方式一:先从常量池查询看是否有"zzp"数据空间,如果有,直接指向;如果没有则重新创建,然后指向。s最终指向的是常量池的空间地址

2、方式二:先在堆中创建空间,里面维护了value属性,指向常量池的zzp空间。如果常量池没有"zzp",重新创建,如果有,直接通过value指向。最终指向的是堆中的空间地址。

3、画出两种方式的内存分布图

在这里插入图片描述


测试题

1)测试题1

String a = "abc";//在常量池查找
String b = "abc";
System.out.println(a.equals(b));//true
System.out.println(a == b);//true
public class StringExercise01 {
    public static void main(String[] args) {
        String a = "abc";
        String b = "abc";
        System.out.println(a.equals(b));//true
        System.out.println(a == b);//true
    }
}
==========控制台输出===========
true
true

2)测试题2

String a = new String("abc");//指向堆中对象 "abc"
String b = new String("abc");
System.out.println(a.equals(b));//true
System.out.println(a == b);//false

3)测试题3

String a = "zzp";//a 指向 常量池的 "zzp"
String b = new String("zzp");//b 指向推中的对象
System.out.println(a.equals(b));//true
System.out.println(a == b);//false
System.out.println(a == b.intern());//true
System.out.println(b == b.intern());//false

知识点:

当调用 intern 方式时,如果池子已经包含一个等于此 String 对象的字符串(用 equals(Object)方法确定),则返回池中字符串。否则,将此 String 对象添加到池子中,并返回此 String 对象的引用
解读:(1)b.intern() 方法最终返回的是常量池的地址(对象)

public class StringExercise03 {
    public static void main(String[] args) {
        String a = "zzp";//a 指向 常量池的 "zzp"
        String b = new String("zzp");//b 指向推中的对象
        System.out.println(a.equals(b));//true
        System.out.println(a == b);//false
        // b.intern() 方法返回常量池的地址
        System.out.println(a == b.intern());//true
        System.out.println(b == b.intern());//false
    }
}
==========控制台输出===========
true
false
true
false

4)测试题4

String s1 = "zzp";//指向常量池 "zzp"
String s2 = "java";//指向常量池 "java"
String s4 = "java";//指向常量池 "java"
String s3 = new String("java");//指向堆中对象 "java"
System.out.println(s2 == s3);//false
System.out.println(s2 == s4);//true
System.out.println(s2.equals(s3));//true
System.out.println(s1 == s2);//false

5)测试题5

Person p1 = new Person();
p1.name = "zzp";//指向常量池 "zzp"
Person p2 = new Person();
p2.name = "zzp";//指向常量池 "zzp"

System.out.println(p1.name.equals(p2.name));//true
System.out.println(p1.name == p2.name);//true 都是指向常量池的地址
System.out.println(p1.name == "zzp");//true 都是指向常量池的地址

String s1 = new String("bcde");
String s2 = new String("bcde");
System.out.println(s1 == s2);//false
public class StringExercise05 {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "zzp";//指向常量池 "zzp"
        Person p2 = new Person();
        p2.name = "zzp";//指向常量池 "zzp"

        System.out.println(p1.name.equals(p2.name));//true
        System.out.println(p1.name == p2.name);//true 都是指向常量池的地址
        System.out.println(p1.name == "zzp");//true 都是指向常量池的地址

        String s1 = new String("bcde");
        String s2 = new String("bcde");
        System.out.println(s1 == s2);//false
    }
}
class Person{
    public String name;
}
==========控制台输出===========
true
true
true
false



字符串的特性

说明

1)String是一个final类,代表不可变的字符序列

2)字符串是不可变的。一个字符串对象一旦被分配,其内容是不可变的。

1、以下语句创建了几个对象?画出内存分布局图
String s1 = “hello”;//从常量池创建 hello
s1 = “haha”;//从常量池创建 haha
//创建了2个对象

在这里插入图片描述


面试题

1)题1

String  a = "hello" + "abc";
创建了几个对象?===> 1个对象
>解读:String  a =  "hello" + "abc"; // ===> 优化等价 String a = "helloabc";
>分析:
>1、编译器不傻,做一个优化,判断创建的常量池对象,是否有引用指向
>2、String  a =  "hello" + "abc"; //==> 优化等价 String a = "helloabc";

2)题2

String a = "hello";//在常量池创建 a对象 hello
String b = "abc";//在常量池创建 b对象 abc
String c = a + b;//创建了几个对象? 3个对象
//关键就是要分析 String c = a + b; 到底是如何执行的

在这里插入图片描述

小结:

底层是 StringBuilder sb = new StringBuilder(); sb.append(a); sb.append(b); sb是在堆中,并且 append是在原来字符串的基础上追加的。
重要规则
String c1 = “ab” + “cd”; 常量相加,看的是池。
String c1 = a + b; 变量相加,是在堆中。

public class StringExercise08 {
    public static void main(String[] args) {
        String a = "hello";
        String b = "abc";
        //解读:
        //1.先创建一个 StringBuilder sb = StringBuilder();
        //2.执行 sb.append("hello");
        //3.sb.append("abc");
        //4.String c = sb.toString()-->new String(value, 0, count);
        //最后其实是 c 指向堆中的对象 (String)value[] -> 池中 "helloabc"
        String c = a + b;

		String d = "helloabc";
        System.out.println(c == d);//false 一个是堆 另一个是常量池
        String e = "hello" + "abc";//指向常量池中
        System.out.println(d == e);//true
    }
}

3)题3

下面代码输出什么,并说明原因

String s1 = "zzp";//s1 指向常量池中的 zzp
String s2 = "java";//s2 指向常量池中的 java
String s5 = "zzpjava";//s5 指向常量池中的 zzpjava
String s6 = (s1 + s2).intern();//s6 指向常量池中的 zzpjava
System.out.println(s5 == s6);//true
System.out.println(s5.equals(s6));//true

4)题4

下列程序运行的结果是什么,尝试画出内存布局图

public class Test1{
	String str = new String("zzp");
	final char[] ch ={'j','a','v','a'};
	public void change(String str, char ch[]){
		str = "java";
		ch[0] = 'h';
	}
	public static void main(String[] args){
		Test1 ex = new Test1();
		ex.change(ex.str, ex.ch);
		System.out.print(ex.str + " and ");
		System.out.println(ex.ch);
	}
}
//最终输出
zzp and hava

在这里插入图片描述



String类的常用方法

说明

String类是保存字符串的常量。每次更新都需要重新开辟空间,效率较低,因此 java设计者提供了 StringBuilderStringBuffer 来增强String的功能,并提高效率。

//看看这段代码
String s = new String("");
for(int i = 0; i < 80000; i++){
	s += "hello";
}
// 80000次开辟空间 消耗软件性能 浪费空间

String类的常用方法一览

  • equals:将此字符串与指定对象进行比较。
  • equalsIgnoreCase:将此 String与其他 String比较
  • length:返回此字符串的长度
  • indexOf:返回指定字符第一次出现的字符串内的索引
  • lastIndexOf:返回指定字符的最后一次出现的字符串中的索引
  • substring:返回一个字符串,该字符串是此字符串的子字符串
  • trim:返回一个字符串,其值为此字符串,并删除任何前导和尾随空格
  • charAt:获取某索引处的字符(返回 char指定索引处的值)
  • toUpperCase:将所有在此字符 String使用默认语言环境的规则大写
  • toLowerCase:将所有在此字符 String使用默认语言环境的规则,以小写
  • concat:将指定的字符串连接到该字符串的末尾
  • compareTo:按字典顺序比较两个字符串
  • toCharArray:将此字符串转换为新的字符数组
  • format:使用指定的格式字符串和参数返回格式化的字符串

String类的常用方法应用实例1

  • equals://区分大小写,判断内容是否相等
  • equalsIgnoreCase://忽略大小写的判断内容是否相等
  • length://获取字段的个数,字符串的长度
  • indexOf://获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回 -1
  • lastIndexOf://获取字符在字符串中最后1次出现的索引,索引从0开始,如果找不到,返回 -1
  • substring://截取指定范围的子串
  • trim://去前后空格
  • charAt:获取某索引处的字符:注意不能使用Str[index]这种方式【不能以数组方式截取,比如:String str = “hello”; str[0]–>错误】
//不能以数组方式截取,
String str = "hello";
//str[0] 错误
//str.charAt[0] => h
public class StringMethod01 {
    public static void main(String[] args) {
        //1.equals 比较内容是否相同,区分大小写
        String str1 = "hello";
        String str2 = "Hello";
        System.out.println(str1.equals(str2));//false
        //2.equalsIgnoreCase 忽略大小写的判断内容是否相等
        String userName = "johN";
        if("john".equalsIgnoreCase(userName)){
            System.out.println("Success!");//Success!
        }else {
            System.out.println("Failure!");
        }
        //3.length 获取字符的个数,字符串的长度
        System.out.println("zzp".length());//3
        //4.indexOf 获取字符在字符串中第1次出现的索引,索引从0开始,如果找不到,返回 -1
        String s1 = "wer@terwe@g";
        int index = s1.indexOf('@');
        System.out.println("index=" + index);//3
        System.out.println("weIndex=" + s1.indexOf("we"));//0
        //5.lastIndexOf 获取字符在字符串中最后1次出现的索引,索引从0开始,如果找不到,返回 -1
        String s2 = "wer@terwe@g@";
        int lastIndexOf = s2.lastIndexOf('@');
        System.out.println("lastIndexOf=" + lastIndexOf);//11
        System.out.println("weLastIndexOf=" + s1.lastIndexOf("we"));//7
        //6.substring 截取指定范围的子串
        String name = "hello,张三";
        //下面 name.substring(6) 从索引6开始截取后面的所有内容
        System.out.println(name.substring(6));//张三
        //下面 name.substring(0,5) 从索引0开始截取,截取到索引 5-1=4 位置
        System.out.println(name.substring(2,5));//llo
        //7.trim 去前后空格
        String str3 = " java  ";
        System.out.println(str3.trim());//java
        //8.charAt 获取某索引处的字符:注意不能使用
        String str4 = "hello";
        System.out.println(str4.charAt(0));//h
    }
}
=====控制台输出========
false
Success!
3
index=3
weIndex=0
lastIndexOf=11
weLastIndexOf=7
张三
llo
java
h

String类的常用方法应用实例2

  • toUpperCase:将所有在此字符 String使用默认语言环境的规则大写
  • toLowerCase:将所有在此字符 String使用默认语言环境的规则,以小写
  • concat:将指定的字符串连接到该字符串的末尾
  • replace:替换字符串中的字符
  • split:分割字符串,对于某些分割字符,我们需要 转义,比如:| \\等

案例:
String poem = “锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦”; 和 文件路径

  • compareTo://比较两个字符串的大小,如果前者大,则返回正数,后者大,则返回负数,如果相等,返回0
  • toCharArray://转换成字符数组
  • format://格式字符串。%s 字符串 %c 字符 %d 整数 %.2f 浮点型
public class StringMethod02 {
    public static void main(String[] args) {
        //1.toUpperCase 将所有在此字符 String使用默认语言环境的规则大写
        String s = "heLLo";
        System.out.println("大写=" + s.toUpperCase(Locale.ROOT));//HELLO
        //2.toLowerCase 将所有在此字符 String使用默认语言环境的规则,以小写
        System.out.println("小写=" + s.toLowerCase(Locale.ROOT));//hello
        //3.concat 将指定的字符串连接到该字符串的末尾
        String s1 = "宝玉";
        s1 = s1.concat("林黛玉").concat("薛宝钗").concat("together");
        System.out.println("s1=" + s1);//宝玉林黛玉薛宝钗together
        //4.replace 替换字符串中的字符
        String s2 = "宝玉 and 林黛玉 林黛玉";
        //在s2中,将 使用 林黛玉 替换成 薛宝钗
        //解读:s2.replace() 方法执行后,放回的结果才是替换过的,
        // 注意对 s2没有任何影响
        String s3 = s2.replace("宝玉","tom");
        System.out.println("s2=" + s2);//宝玉 and 林黛玉 林黛玉
        System.out.println("s3=" + s3);//tom and 林黛玉 林黛玉
        //5.split:分割字符串,对于某些分割字符,我们需要 转义,比如:| \\等
        String poem = "锄禾日当午,汗滴禾下土,谁知盘中餐,粒粒皆辛苦";
        //解读:
        //1.以逗号, 为标准对 poem 进行分割,返回一个数组
        //2.在对字符串进行分割时,如果有特殊字符,需要加入 转义符 \
        String[] split = poem.split(",");
        System.out.println("---poem 以逗号分割,如下----");
        for (String str : split) {
            System.out.println(str);
        }
        //我们需要 转义,比如:| \\等
        poem = "E:\\aaa\\bbb";
        split = poem.split("\\\\");
        System.out.println("---poem 以转义\\\\字符分割,如下----");
        for (String str : split) {
            System.out.println(str);
        }
        //6.toCharArray 转换成字符数组
        String s4 = "happy";
        char[] chars = s4.toCharArray();
        System.out.println("---s4.toCharArray()转换char数组,如下----");
        for (char ch : chars) {
            System.out.println(ch);
        }
        //7.compareTo 比较两个字符串的大小,如果前者大,则返回正数,
        // 后者大,则返回负数,如果相等,返回0
        //解读;
        //(1) 如果长度相同,并且每个字符也相同,就返回 0
        //(2) 如果长度相同或者不相同,但是在进行比较,可以区分大小
        //    就返回  if (c1 != c2) {
        //                return c1 - c2;
        //            }
        //(3) 如果前面的部分都相同,就返回 str1.len - str2.len
        String s5 = "jchn";
        String s6 = "jack";
        //返回值是 'c' - 'a' = 2的值
        System.out.println(s5.compareTo(s6));//2
        //8.format 格式字符串
        /*
        占位符:
         %s 字符串 %c 字符 %d 整数 %.2f 浮点型
         */
        String name = "john";
        int age = 20;
        double score = 98.3 / 3;
        char gender = '男';
        //将所有的信息拼接在一个字符串
        String info1 = "我的姓名是" + name + "年龄是" + age +
            "性别是" + gender + ",成绩是" + score;
        System.out.println("info1=" + info1);
        //解读:
        //1. %s, %c, %d, %.2f 称为占位符
        //2. 这些占位符由后面的变量来替换
        //3. %s 表示后面由 字符串替换
        //4. %d 是整数来替换
        //5. %.2f 表示后面由 小数来替换,替换后,只会保留小数点两位(四舍五入处理)
        //6. %c 使用char类型替换
        String formatSrt = "我的姓名是%s年龄是%d性别是%c,成绩是%.2f";
        String info2 = String.format(formatSrt,name,age,gender,score);
        System.out.println("info2=" + info2);
    }
}
==============控制台输出================
大写=HELLO
小写=hello
s1=宝玉林黛玉薛宝钗together
s2=宝玉 and 林黛玉 林黛玉
s3=tom and 林黛玉 林黛玉
---poem 以逗号分割,如下----
锄禾日当午
汗滴禾下土
谁知盘中餐
粒粒皆辛苦
---poem 以转义\\字符分割,如下----
E:
aaa
bbb
---s4.toCharArray()转换char数组,如下----
h
a
p
p
y
2
info1=我的姓名是john年龄是20性别是男,成绩是32.766666666666666
info2=我的姓名是john年龄是20性别是男,成绩是32.77



三、StringBuffer和StringBuilder类

StringBuffer类

基本介绍

  • java.lang.StringBuffer 代表可变的字符序列,可以对字符串内容进行增删
  • 很多方法于String相同,但StringBuffer是可变长度的
  • StringBuffer 是一个StringBuffer

在这里插入图片描述

package java.lang;

/**
 * 1. StringBuffer 是final 类
 * 2. 实现了 Serializable 接口,可以保存到文件,或者网络传输
 * 3. 继承了抽象类 AbstractStringBuilder
 * 4. AbstractStringBuilder 属性 byte[] value,保存的字符序列
 */
public final class StringBuffer
    extends AbstractStringBuilder
    implements java.io.Serializable, Comparable<StringBuffer>, CharSequence{
    .....

}
package java.lang;

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value
	....
}

String VS StringBuffer

1)String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率低【private final char value[];】

2)StringBuffer 保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率高【char[] value; //这个存放在堆中】

public class StringBuffer01 {
    public static void main(String[] args) {
        //解读:
        //1. StringBuffer 的直接父类是 AbstractStringBuilder
        //2. StringBuffer 实现了 Serializable,即StringBuffer的对象可以串行化
        //3. 在父类中 AbstractStringBuilder 有属性 char[] value,不是final
        //   该 value 数组存放 字符串内容,引用存放在堆中的,不是常量池
        //4. StringBuffer 是一个 final 类,不能被继承
        //5. 因为StringBuffer 字符内容是存在 char[] value,使用在变化(增加/删除)
        //   不用每次都更换地址(即不是每次创建新的对象),所以效率高于 String
        StringBuffer stringBuffer = new StringBuffer("hello");
    }
}

StringBuffer的构造器

在这里插入图片描述

public class StringBuffer02 {
    public static void main(String[] args) {
        //构造器的使用
        //解读:
        //1. 创建一个 大小为 16的 char[],用于存放字符内容
        /*
            public StringBuffer() {
                super(16);
            }
         */
        StringBuffer stringBuffer = new StringBuffer();

        //2. 通过构造器指定 char[] 大小
        /*
            public StringBuffer(int capacity) {
                super(capacity);
            }
         */
        StringBuffer stringBuffer1 = new StringBuffer(100);

        //3. 通过给一个String 创建 StringBuffer,char[] 大小就是 str.length + 16
        /*
            public StringBuffer(String str) {
                super(str.length() + 16);
                append(str);
            }
         */
        StringBuffer stringBuffer2 = new StringBuffer("hello");
    }
}

String和StringBuffer相互转换

在开发中,我们经常需要将String 和 StringBuffer进行转换,看看然后实现

public class StringAndStringBuffer {
    public static void main(String[] args) {
        // String --> StringBuffer
        String str = "hello";
        //方式1 使用构造器
        //注意:返回的才是StringBuffer对象,对str 本身没有影响
        StringBuffer b1 = new StringBuffer(str);
        //方式2 使用的是append方法
        StringBuffer b2 = new StringBuffer();
        b2.append(str);

        //StringBuffer --> String
        StringBuffer b3 = new StringBuffer("zzp");
        //方式1 使用StringBuffer提供的 toString方法
        String str2 = b3.toString();
        //方式2 使用String构造器
        String str3 = new String(b3);
    }
}

StringBuffer类常见方法

1)增 append
2)删 delete(start, end)
3)改 replace(start, end, string)//将start—end 间的内容替换掉,不含end
4)查 indexOf //查找子串在字符串第1次出现的索引,如果找不到返回-1
5)插 insert
6)获取长度 length

public class StringBufferMethod {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("hello");
        //增
        s.append(",");//hello,
        s.append("张三丰");//hello,张三丰
        s.append("赵敏").append(100).append(true).append(10.5);
        System.out.println(s);//hello,张三丰赵敏100true10.5
        //删
        /*
         * 删除索引为 >= start && < end 处的字符
         * 解读:删除 11~14的字符【不包含14】 [11~14)
         */
        s.delete(11,14);
        System.out.println(s);//hello,张三丰赵敏true10.5
        //改
        //解读:使用 周芷若 替换 索引9~11的字符 [9~11)
        s.replace(9,11,"周芷若");
        System.out.println(s);//hello,张三丰周芷若true10.5
        //查找指定的字符串第一次出现的索引,如果找不到返回-1
        int indexOf = s.indexOf("张三丰");
        System.out.println(indexOf);//6
        //插
        //解读:在索引为9位置插入 "赵敏",原来索引为9的内容自动后移
        s.insert(9,"赵敏");
        System.out.println(s);//hello,张三丰赵敏周芷若true10.5
        //长度
        System.out.println(s.length());//22
        System.out.println(s);//hello,张三丰赵敏周芷若true10.5
    }
}
=============控制台输出======================
hello,张三丰赵敏100true10.5
hello,张三丰赵敏true10.5
hello,张三丰周芷若true10.5
6
hello,张三丰赵敏周芷若true10.5
22
hello,张三丰赵敏周芷若true10.5

StringBuffer类测试题

1、看看下面代码输出什么?为什么?

String str = null;//ok
StringBuffer sb = new StringBuffer();//ok
sb.append(str);//看底层源码,底层调用的是父类的 AbstractStringBuilder.appendNull()方法
/* 源码方法
    @Override
    public synchronized StringBuffer append(String str) {
        toStringCache = null;
        super.append(str);
        return this;
    }
    public AbstractStringBuilder append(String str) {
	     if (str == null)
	         return appendNull();
	     int len = str.length();
	     ensureCapacityInternal(count + len);
	     str.getChars(0, len, value, count);
	     count += len;
	     return this;
	 }
	 //当传的参数为 null ==> 转成 "null"
	 private AbstractStringBuilder appendNull() {
        int c = count;
        ensureCapacityInternal(c + 4);
        final char[] value = this.value;
        value[c++] = 'n';
        value[c++] = 'u';
        value[c++] = 'l';
        value[c++] = 'l';
        count = c;
        return this;
    }

*/
System.out.println(sb.length());//4

System.out.println(sb);//null
StringBuffer sb1 = new StringBuffer(str);//null对象  看底层源码
/*  StringBuffer 构造器,会抛出NullPointerException空指针异常
	public StringBuffer(String str) {
        super(str.length() + 16);//str=null ==> str.length 异常NullPointerException
        append(str);
    }
*/
System.out.println(sb1);   
public class StringBufferExercise01 {
    public static void main(String[] args) {
        String str = null;//ok
        StringBuffer sb = new StringBuffer();//ok
        sb.append(str);//看底层源码,底层调用的是父类的 AbstractStringBuilder.appendNull()方法
        /* 源码方法
            @Override
            public synchronized StringBuffer append(String str) {
                toStringCache = null;
                super.append(str);
                return this;
            }
            public AbstractStringBuilder append(String str) {
                 if (str == null)
                     return appendNull();
                 int len = str.length();
                 ensureCapacityInternal(count + len);
                 str.getChars(0, len, value, count);
                 count += len;
                 return this;
             }
             //当传的参数为 null ==> 转成 char[] = "null"
             private AbstractStringBuilder appendNull() {
                int c = count;
                ensureCapacityInternal(c + 4);
                final char[] value = this.value;
                value[c++] = 'n';
                value[c++] = 'u';
                value[c++] = 'l';
                value[c++] = 'l';
                count = c;
                return this;
            }

        */
        System.out.println(sb.length());//4

        System.out.println(sb);//null
        StringBuffer sb1 = new StringBuffer(str);//null对象  看底层源码
        /*  StringBuffer 构造器,会抛出NullPointerException空指针异常
            public StringBuffer(String str) {
                super(str.length() + 16);//str=null ==> str.length 异常NullPointerException
                append(str);
            }
        */
        System.out.println(sb1);
    }
}

在这里插入图片描述

2、输入商品名称和商品价格,要求打印效果示例,使用前面学习的方法完成;

商品名 商品价格
手机 123,456.59 //比如价格 3,456,789.88

要求:价格的小数点前面每三位用逗号隔开,在输出

public class StringBufferExercise02 {
    public static void main(String[] args) {
        /*
            输入商品名称和商品价格,要求打印效果示例,使用前面学习的方法完成;
            商品名 商品价格
            手机 123,456.59 //比如价格 3,456,789.88
            要求:价格的小数点前面每三位用逗号隔开,在输出

            思路分析:
            1. 定义一个Scanner 对象,接收用户输入的 价格(String)
            2. 希望使用到 StringBuffer的 insert方法,需要将 String 转成 StringBuffer
            3. 然后使用相关方法进行字符串的处理
            代码实现
         */
        //new Scanner(System.in);
        String price = "1234567.59";
        StringBuffer buffer = new StringBuffer(price);
        //先完成一个最简单的实现 123,456.59
        //找到小数点的索引,然后在该位置的前3位,插入,即可
//        int i = buffer.indexOf(".");
//        buffer = buffer.insert(i - 3, ",");
        //上面的两步需要做一个循环处理,才是正确的
        for(int i = buffer.lastIndexOf(".") - 3; i > 0; i -= 3){
            buffer = buffer.insert(i, ",");
        }
        System.out.println(buffer);
    }
}
========控制台输出========
1,234,567.59



StringBuilder类

基本介绍

1)一个可变的字符序列。此类通过了一个与 StringBuffer 兼容的 API ,但不保证同步(StringBuilder 不是线程安全)。该类被设计用作 StringBuffer 的一个简易替换,用在字符串缓存区被单个线程使用的时候。如果可能,建议优先采用该类,因为大多数实现中,它比 StringBuffer 要快

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

在这里插入图片描述


StringBuilder常用方法

StringBuilder 和 StringBuffer 均代表可变的字符序列,方法是一样的,使用使用和StringBuilder一样

StringBuilder 源码:

package java.lang;

/*
* 1. StringBuilder 是final
* 2. 继承  AbstractStringBuilder,属性 char[] value,内容存到 value
* 3. 实现了 Serializable 接口,序列化(所谓的序列化即可以保存类型和数据本身)
*/
public final class StringBuilder
    extends AbstractStringBuilder
    implements java.io.Serializable, CharSequence
{....}
package java.lang;

abstract class AbstractStringBuilder implements Appendable, CharSequence {
    /**
     * The value is used for character storage.
     */
    char[] value;
    ...
}
public class StringBuilder01 {
    public static void main(String[] args) {
        //解读:
        //1. StringBuilder 继承了 AbstractStringBuilder 类
        //2. 实现了 Serializable 接口,说明StringBuilder对象是可以串行化(对象可以网络传输,也可以保存到文件)
        //3. StringBuilder 是final类,不能被继承
        //4. StringBuilder 对象字符序列仍然是存放在其父类 AbstractStringBuilder的 char[] value;
        //    因此,字符序列是对堆中
        //5. StringBuilder 的方法,没有做互斥的处理,即没有synchronized 关键字,
        //   因此在单线程的情况下使用 StringBuilder
        StringBuilder stringBuilder = new StringBuilder();
    }
}

String、StringBuffer 和StringBuilder的比较

1)StringBufferStringBuilder 非常类似,均代表可变的字符序列,而且方法也一样

2)String:不可变字符序列,效率低,但复用率高

3)StringBuffer:可变字符序列、效率较高(赠删)、线程安全

4)StringBuilder:可变字符序列,效率最高、线程不安全

5)String使用注意说明:

String s = "a";//创建了一个字符串
s += "b";//实际上原来的 "a" 字符串对象已经丢弃了,现在又产生了一个字符串 s + "b"(也就是 "ab")。
//如果多次执行这些改变串的内容的操作,会导致大量副本字符串对象留在内存中,降低效率。
//如果这样的操作方法到循环中,会极大影响程序性能 
// ==> 结论:如果我们对String 做大量修改,不要使用String

String、StringBuffer 和StringBuilder的效率测试

效率: StringBuilder > StringBuffer > String

public class StringVsStringBufferVsStringBuilder {
    public static void main(String[] args) {
        long startTime = 0l;
        long endTime = 0l;
        
        StringBuffer buffer = new StringBuffer("");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {//StringBuffer 拼接 20000次
            buffer.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuffer的执行时间:" + (endTime - startTime));

        StringBuilder builder = new StringBuilder("");
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {//StringBuilder 拼接 20000次
            builder.append(String.valueOf(i));
        }
        endTime = System.currentTimeMillis();
        System.out.println("StringBuilder的执行时间:" + (endTime - startTime));

        String text = "";
        startTime = System.currentTimeMillis();
        for (int i = 0; i < 20000; i++) {//String 拼接 20000次
            text += String.valueOf(i);
        }
        endTime = System.currentTimeMillis();
        System.out.println("String的执行时间:" + (endTime - startTime));
    }
}
=========控制台输出=========
StringBuffer的执行时间:6
StringBuilder的执行时间:4
String的执行时间:1797

String、StringBuffer 和StringBuilder的选择

使用原则,结论:

  1. 如果字符串存在大量的修改操作,一般使用 StringBuffer 或 StringBuilder
  2. 如果字符串存在大量的修改操作,并在单线程的情况下,使用StringBuilder
  3. 如果字符串存在大量的修改操作,并在多线程的情况下,使用 StringBuffer
  4. 如果我们字符串很少修改,被多个对象引用,使用String,比如配置信息等



四、Math类

基本介绍

Math 类包含用于执行基本数学运算的方法,如初等指数、对数、平方根和三角函数。

方法一览(均为静态方法)

连接
在这里插入图片描述



Math类常见方法应用案例

演示Math 类常见的方法

1)abs:绝对值
2)pow:求幂
3)ceil:向上取整
4)floor:向下取整
5)round:四舍五入
6)sqrt:求开方
7)random:求随机数

思考:请写出获取 a-b之间一个随机整数,a,b均为整数

8)max:求两数的最大值
9)min:求两数的最小值

public class MathMethod {
    public static void main(String[] args) {
        //Math常用的静态方法
        //1. abs 绝对值
        int abs = Math.abs(-9);
        System.out.println(abs);//9
        //2. pow 求幂
        double pow = Math.pow(2,4);//2的4次方
        System.out.println(pow);//16
        //3. ceil 向上取整,返回 >= 该参数的最小整数(转成double)
        double ceil = Math.ceil(3.9);
        System.out.println(ceil);//4.0
        //4. floor 向下取整,返回 <= 该参数的最大整数(转成double)
        double floor = Math.floor(4.01);
        System.out.println(floor);//4.0
        //5. round 四舍五入 Math.floor(该参数 + 0.5);
        long round = Math.round(5.51);
        System.out.println(round);//6
        //6. sqrt 求开方
        double sqrt = Math.sqrt(9.0);
        System.out.println(sqrt);//3.0
        System.out.println("-------------");
        //7. random 返回随机数 [0 - 1)
        //   random 返回的是 0<= x < 1 之间的一个随机小数
        //思考:请写出获取 a-b之间一个随机整数,a,b均为整数,比如:a=2,b=7
        // 即返回一个数 x: 2<= x <= 7
        //解读:Math.random() * (b-a) 返回的就是 0 <= 数 <= b-a
        //(1) (int)a <= x <= (int)(a + Math.random() * (b-a +1))
        //(2) 使用具体的数介绍 a=2 b=7
        //    (int)(a + Math.random() * (b-a+1)) = (int)(2 + Math.random() * 6)
        //    Math.random() * 6 返回的是 0 < x < 6 的一个小数
        //    2 + Math.random() * 6 返回就是 2 <= x < 8 的小数
        //    (int)(2 + Math.random() * 6) = 2 < x <= 7
        //(3) 公式就是 (int)(a + Math.random() * (b-a +1))

        for (int i = 0; i < 10; i++) {
            System.out.println((int)(2 + Math.random() * (7-2+1)) );
        }
        System.out.println("-------------");
        //max,min 返回最大值 和 最小值
        System.out.println("max="+ Math.max(12,20));//20
        System.out.println("min=" + Math.min(12,20));//12
    }
}
=======控制台输出========
9
16.0
4.0
4.0
6
3.0
-------------
4
2
4
4
6
4
3
6
4
4
-------------
max=20
min=12

练习题:获取 a - b 之间的一个随机整数

公式: (int)(a + Math.random() * (b - a +1))



五、Arrays类

Arrays类常见方法应用案例

Arrays里面包含了一系列静态方法,用于管理或操作数组(比如排序和搜索)。

1)toString:返回数组的字符串形式

Arrays.toString(arr);

2)sort:排序(自然排序和定制排序)

Integer arr[] = {1, -1, 7, 0, 89};
Arrays.sort(arr);

public class ArraysMethod01 {
    public static void main(String[] args) {
        Integer[] integers = {1,20,90};
        //遍历显示数组
//        for (int i = 0; i < integers.length; i++) {
//            System.out.println(integers[i]);
//        }
        //直接使用Arrays.toString方法,显示数组信息
        System.out.println(Arrays.toString(integers));//[1, 20, 90]

        //演示 sort方法使用
        Integer[] arr = {1,-1,50,20,24};
        //进行排序
        //1. 可以直接使用冒泡排序,也可以使用Arrays提供的sort方法排序
        //2. 因为数组是引用类型,所以通过sort排序后,会直接影响到 实参 arr
//        Arrays.sort(arr);//默认排序方法 从小到大
//        System.out.println("Arrays.sort排序后=" + Arrays.toString(arr));//[-1, 1, 20, 24, 50]
        //3. sort方法是重载的,也可以通过传入一个接口 Comparator 实现定制排序
        //4. 调用 定制排序 时,传入两个参数 (1) 排序的数组 arr
        //      (2) 实现了 Comparator 接口的匿名内部类,要求实现 compare方法
        //5. 这里体现了接口编程的方式 看源码
        /* (1)Arrays.sort(T[] a, Comparator<? super T> c)
           (2)TimSort.sort()方法
           (3)再调用TimSort.binarySort方法,
                会关键动态绑定机制,c.compare执行传入的匿名内部类的 compare()方法,
                关键代码如下:
            while (left < right) {
                int mid = (left + right) >>> 1;
                //在binarySort方法底层,会通过匿名内部类的compare方法来决定排序的顺序
                if (c.compare(pivot, a[mid]) < 0)
                    right = mid;
                else
                    left = mid + 1;
             }
           (4)public int compare(Object o1, Object o2) 返回的值>0 还是 <0 会影响这个排序的结果
           这里充分体现了 接口编程+动态绑定+匿名内部类的综合使用
         */
        //定制排序
        Arrays.sort(arr, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Integer i1 = (Integer) o1;
                Integer i2 = (Integer) o2;
                return i2 - i1;
            }
        });
        System.out.println("Arrays.sort定制排序后=" + Arrays.toString(arr));
    }
}
===========控制台输出=========
[1, 20, 90]
Arrays.sort定制排序后=[50, 24, 20, 1, -1]

结合冒泡 + 定制(使用Comparator接口) 排序方法,演示

public class ArraysSortCustom {
    public static void main(String[] args) {
        int[] arr = {1,0,-2,12,3};
        //bubble01(arr);
        bubble02(arr, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                Integer i1 = (Integer) o1;
                Integer i2 = (Integer) o2;
                return i1 - i2;//从小到大
//                return i2 - i1;//从大到小
            }
        });
        System.out.println("排序后=" + Arrays.toString(arr));

    }
    //使用冒泡排序完成 从小到大排序
    public static void bubble01(int[] arr){
        int temp = 0;
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - i -1; j++) {
                if(arr[j] > arr[j + 1]){
                    temp = arr[j + 1];
                    arr[j + 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }

    //结合冒泡 + 定制
    public static void bubble02(int[] arr, Comparator c){
        int temp = 0;
        for (int i = 0; i < arr.length - 1; i++) {
            for (int j = 0; j < arr.length - i -1; j++) {
                //数组的排序由这 c.compare(arr[j], arr[j+1])返回的值决定
                if(c.compare(arr[j], arr[j+1]) > 0){
                    temp = arr[j + 1];
                    arr[j + 1] = arr[j];
                    arr[j] = temp;
                }
            }
        }
    }
}

3)binarySearch:通过二分搜索法进行查找,要求必须排好序

int index = Arrays.binarySearch(arr, 3);

4)copyOf:数组元素的复制

Integer[] newArr = Arrays.copyOf(arr, arr.length);

5)fill:数组元素的填充

Integer[] num = new Integer[]{9, 3, 2};
Arrays.fill(num, 99);

6)equals:比较两个数组元素内容是否完全一致

boolean equals = Arrays.equals(arr, arr2);

7)asList:将一组值,转换成list

List<Integer> asList = Arrays.asList(2,3,4,5);
System.out.println(“asList=” + asList);

public class ArraysMethod02 {
    public static void main(String[] args) {
        Integer[] arr = {1, 2, 90, 123, 567};
        //binarySearch:通过二分搜索法进行查找,要求必须排好序
        //解读:
        //1. 使用 binarySearch 二叉查找
        //2. 要求该数组是有序的。如果该数组是无序的,不能使用 binarySearch
        //3. 如果数组中不存在该元素,就返回 -(low + 1);  // key not found.
        int index = Arrays.binarySearch(arr, 123);
        System.out.println("index=" + index);

        //copyOf 数组元素的复制
        //解读:
        //1. 从 arr 数组中,拷贝 arr.length个元素到 newArr数组中
        //2. 如果拷贝的长度 > arr.length 就在数组后面 增加 null
        //3. 如果拷贝长度 <0 就抛出异常 NegativeArraySizeException
        //4. 该方法的底层使用的是 System.arraycopy()
        Integer[] newArr = Arrays.copyOf(arr, arr.length +1);
        System.out.println("newArr=" + Arrays.toString(newArr));//[1, 2, 90, 123, 567, null]

        //fill 数组元素的填充
        Integer[] num = new Integer[]{9, 3, 2};
        //解读:
        //1. 使用 99 去填充 num数组,可以理解成是替换原来的元素
        Arrays.fill(num, 99);
        System.out.println("填充后的数组=" + Arrays.toString(num));//[99, 99, 99]

        //equals 比较两个数组元素内容是否完全一致
        Integer[] arr2 = {1, 2, 90, 123, 567};
        //解读:
        //1. 如果arr 和 arr2 数组的元素一样,则返回true
        //2. 如果不是完全一样,就返回 false
        boolean equals = Arrays.equals(arr, arr2);
        System.out.println("equals数组比较=" + equals);//true

        //asList:将一组值,转换成list
        //解读:
        //1. asList方法,会将 (2,3,4,5)数据转成一个List集合
        //2. 返回的 asList 编译类型 List
        //3. asList 运行类型 class java.util.Arrays$ArrayList
        //      ArrayList 是Arrays类的静态内部类
        //   private static class ArrayList<E> extends AbstractList<E>
        //        implements RandomAccess, java.io.Serializable
        List asList = Arrays.asList(2,3,4,5);
        System.out.println("asList=" + asList);
        System.out.println("asList的运行类型:" + asList.getClass());
    }
}
===========控制台输出=========
index=3
newArr=[1, 2, 90, 123, 567, null]
填充后的数组=[99, 99, 99]
equals数组比较=true
asList=[2, 3, 4, 5]
asList的运行类型:class java.util.Arrays$ArrayList

Arrays类练习

案例:自定义Book类,里面包含name和price,按price排序(从大到小)。要求使用两种方式排序,有一个 Book[] books = 4 本书对象。

使用前面学习过的传递 实现Comparator接口匿名内部类,也称为定制排序。可以按照 price (1)从大到小(2)从小到大(3)按照书面长度从大到小

Book[] books = new Book[4];
books[0] = new Book("红楼梦", 100);
books[1] = new Book("西游记~", 120);
books[2] = new Book("青年文摘~", 10);
books[3] = new Book("java从入门到放弃~", 300);
public class ArraysExercise {
    public static void main(String[] args) {
        /*
        自定义Book类,里面包含name和price,按price排序(从大到小)。
        要求使用两种方式排序,有一个 Book[] books = 4 本书对象。
        使用前面学习过的传递 实现Comparator接口匿名内部类,也称为定制排序。
        可以按照 price (1)从大到小(2)从小到大(3)按照书面长度从大到小
         */
        Book[] books = new Book[4];
        books[0] = new Book("红楼梦", 100);
        books[1] = new Book("西游记~", 120);
        books[2] = new Book("青年文摘~", 10);
        books[3] = new Book("java从入门到放弃~", 300);

        //(1)price从大到小
        Arrays.sort(books, new Comparator() {
            //这里是对Book数组排序,因此 o1,o2就是Book对象
            @Override
            public int compare(Object o1, Object o2) {
                Book book1 = (Book) o1;
                Book book2 = (Book) o2;
                double priceVal = book2.getPrice() - book1.getPrice();
                //这里进行了一个转换
                //如果发现返回结果和我们输出的不一致,就修改 1 和 -1 的位置
                if(priceVal > 0){
                    return 1;
                }else if(priceVal < 0){
                    return -1;
                }else {
                    return 0;
                }
            }
        });
        System.out.println(Arrays.toString(books));
        //(2)price从小到大
        Arrays.sort(books, new Comparator() {
            //这里是对Book数组排序,因此 o1,o2就是Book对象
            @Override
            public int compare(Object o1, Object o2) {
                Book book1 = (Book) o1;
                Book book2 = (Book) o2;
                double priceVal = book2.getPrice() - book1.getPrice();
                //这里进行了一个转换
                //如果发现返回结果和我们输出的不一致,就修改 1 和 -1 的位置
                if(priceVal > 0){
                    return -1;
                }else if(priceVal < 0){
                    return 1;
                }else {
                    return 0;
                }
            }
        });
        System.out.println(Arrays.toString(books));

        //(3)按照书面长度从大到小
        Arrays.sort(books, new Comparator() {
            //这里是对Book数组排序,因此 o1,o2就是Book对象
            @Override
            public int compare(Object o1, Object o2) {
                Book book1 = (Book) o1;
                Book book2 = (Book) o2;
                //按照书面的长度排序
                return book2.getName().length() - book1.getName().length();
            }
        });
        System.out.println(Arrays.toString(books));
    }
}
class Book{
    private String name;
    private double price;

    public Book(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public double getPrice() { return price; }
    public void setPrice(double price) { this.price = price; }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}
===========控制台输出=========
[Book{name='java从入门到放弃~', price=300.0}, Book{name='西游记~', price=120.0}, Book{name='红楼梦', price=100.0}, Book{name='青年文摘~', price=10.0}]
[Book{name='青年文摘~', price=10.0}, Book{name='红楼梦', price=100.0}, Book{name='西游记~', price=120.0}, Book{name='java从入门到放弃~', price=300.0}]
[Book{name='java从入门到放弃~', price=300.0}, Book{name='青年文摘~', price=10.0}, Book{name='西游记~', price=120.0}, Book{name='红楼梦', price=100.0}]



六、System类

System类常见方法和案例

1)exit:退出当前程序

2)arraycopy:复制数组元素,比较适合底层调用,一般使用 Arrays.copyOf 完成复制数组。

int[] src = {1, 2, 3};
int[] dest = new int[3];
System.arraycopy(src, 0, dest, 0, 3);

3)currentTimeMillis:返回当前时间距离 1970-1-1 的毫秒数

4)gc:运行垃圾回收机制 System.gc();

public class System_ {
    public static void main(String[] args) {
        //exit:退出当前程序
        System.out.println("ok1");
        //解读:
        //1. exit(0) 表示程序退出
        //2. 0 表示一个状态,正常的状态
        //System.exit(0);
        System.out.println("ok2");

        //arraycopy:复制数组元素,比较适合底层调用,
        // 一般使用 Arrays.copyOf 完成复制数组。
        int[] src = {1, 2, 3};
        int[] dest = new int[3];// dest 当前是 {0,0,0}
        //解读:
        //1. 主要是搞清楚这5个参数的含义
        //2.
        //     src: 源数组
        //     * @param      src      the source array.
        //     srcPos: 从源数组的哪个索引位置开始拷贝
        //     * @param      srcPos   starting position in the source array.
        //     dest: 目标数组,即把源数组的数据拷贝到哪个数组
        //     * @param      dest     the destination array.
        //     destPos: 把源数组的数据拷贝到 目标数组的哪个索引
        //     * @param      destPos  starting position in the destination data.
        //     length: 从源数组拷贝多少个数据到目标数组
        //     * @param      length   the number of array elements to be copied.
        System.arraycopy(src, 0, dest, 0, src.length);
        //int[] src = {1, 2, 3};
        System.out.println("dest=" + Arrays.toString(dest));//[1, 2, 3]

        //currentTimeMillis:返回当前时间距离 1970-1-1 的毫秒数
        System.out.println(System.currentTimeMillis());
        //gc:运行垃圾回收机制 System.gc();
        System.gc();
    }
}



七、BigInteger类和BigDecimal类

BigInteger和BigDecimal介绍

应用场景:

1)BigInteger适合保存比较大的整型
2)BigDecimal适合保存精度更高的浮点型(小数)


BigInteger和BigDecimal常见方法

1)add
2)subtract
3)multiply
4)divide

BigInteger演示:

public class BigInteger_ {
    public static void main(String[] args) {
        //一般使用long类型
        //long l = 23432432423428989999939L;//报错 超出long范围
        //System.out.println("l=" + l);
        //当我们编程中,需要处理很大的整数,long 不够用
        //可以使用 BigInteger的类来处理
        BigInteger bigInteger = new BigInteger("23432432423428989999939");
        BigInteger bigInteger2 = new BigInteger("100");
        System.out.println("bigInteger=" + bigInteger);
        //解读:
        //1. 在对 BigInteger 进行加减乘除的时候,需要使用对应的方法,不能直接进行 +-*/
        //2. 可以创建一个 要操作的 BigInteger 然后进行相应操作
        BigInteger add = bigInteger.add(bigInteger2);
        System.out.println("add=" + add);//加
        BigInteger subtract = bigInteger.subtract(bigInteger2);//减
        System.out.println("subtract=" + subtract);
        BigInteger multiply = bigInteger.multiply(bigInteger2);//乘
        System.out.println("multiply=" + multiply);
        BigInteger divide = bigInteger.divide(bigInteger2);//除
        System.out.println("divide=" + divide);
    }
}

BigDecimal 演示:

public class BigDecimal_ {
    public static void main(String[] args) {
        //当我们需要保存一个 精度很高的数时,double 不够用
        //可以使用 BigDecimal
//        double d = 199.1111111114444444111333333333333d;
//        System.out.println(d);
        BigDecimal bigDecimal = new BigDecimal("199.1111111114444444111333333333333");
        System.out.println(bigDecimal);

        //解读:
        //1. 如果对 BigDecimal进行运算,比如加减乘除,需要对应的方法
        //2. 需要创建一个需要操作的 BigDecimal 然后调用相应的方法即可
        BigDecimal bigDecimal2 = new BigDecimal("1.1");
        System.out.println(bigDecimal.add(bigDecimal2));//加
        System.out.println(bigDecimal.subtract(bigDecimal2));//减
        System.out.println(bigDecimal.multiply(bigDecimal2));//乘
        //可能抛出异常(除不尽): java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
        //System.out.println(bigDecimal.divide(bigDecimal2));//除
        //在调用divide 方法时,指定精度即可.
        //BigDecimal.ROUND_CEILING:如果有无限循环小数,就会保留 分子 的精度
        System.out.println(bigDecimal.divide(bigDecimal2, BigDecimal.ROUND_CEILING));
    }
}



八、Date日期类、Calendar日历以及新的日期

第一代日期类

1)Date:精确到毫秒,代表特定的瞬间

在这里插入图片描述

2)SimpleDateFormat:格式和解析日期的类。

SimpleDateFormat 格式和解析日期的具体类,它允许进行格式化(日期 -> 文本)、解析(文本 -> 日期)和规范化。

字母日期或时间元素表示示例
GEra 标志符TextAD
yYear1996;96
M年中的月份MonthJuly; Jul; 07
w年中周数Number27
W月份中的周数Number2
D年中的天数Number189
d月份中天数Number10
F月份中星期Number2
E星期中的天数TextTuesday, Tue
aAm/pm 标记TextPM
H一天中小时数(0-23)Number0
k一天中小时数(1-24)Number24
Kam/pm 中的小时数(0-11)Number0
ham/pm 中的小时数(1-12)Number12
m小时中的分钟Number30
s分钟中的秒数Number55
S毫秒数Number978
z时区General time zonePacific Standard Time; PST; GMT-08:00
Z时区RFC 822 time zone-0800
X时区ISO 8601 time zone-08; -0800; -08:00

3)应用实例

public class Date01 {
    public static void main(String[] args) throws ParseException {
        //解读:
        //1. 获取当前系统时间
        //2. 这里的Date 类在java.util包
        //3. 默认输出的日期格是国外的方式,因此通常需要对格式进行转换
        Date d1 = new Date();//获取当前系统时间
        System.out.println("当前日期=" + d1);
        Date d2 = new Date(9234567);//通过指定毫秒数得到时间
        System.out.println("d2=" + d2);//获取某个时间对应的毫秒数 d2.getTime()

        //解读:
        //1. 创建 SimpleDateFormat对象,可以指定相应的格式
        //2. 这里的格式使用的字母是规定好的,不能乱写
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
        String format = sdf.format(d1);//format:将日期转换成指定的字符串
        System.out.println("当前日期=" + format);

        //解读:
        //1.可以把一个格式化的字符串 转成对应的 Date
        //2.得到Date 仍然在输出时,还是按照国外的形式,如果希望指定格式输出,需要转换
        //3.在把String -> Date ,使用的 sdf 格式需要和给的String的格式一样,否则会抛出异常ParseException
        String s = "1996年01月01日 10:20:30 星期一";
        Date parse = sdf.parse(s);
        System.out.println("parse=" + parse);
        System.out.println("parse=" + sdf.format(parse));
    }
}

第二代日期类

1)第二代日期类,主要就是 Calendar类(日历)

在这里插入图片描述

package java.util;

public abstract class Calendar implements Serializable, 
Cloneable, Comparable<Calendar> {

2)Calendar 类是一个抽象类,它为特定瞬间与一组诸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等 日历字段 之间转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法

3)应用实例

public class Calendar_ {
    public static void main(String[] args) {
        //解读:
        //1. Calendar是一个抽象类,并且是构造器是private
        //2. 可以通过 getInstance() 来换取实例
        //3. 通过大量的方法和字段通过给程序员使用
        //4. Calendar没有提供对应的格式化的类,因此需要程序员自己组合来输出
        //5. 如果我们需要按照 24小时进制 Calendar.HOUR ==> Calendar.HOUR_OF_DAY
        Calendar c = Calendar.getInstance();//创建日历类对象
        System.out.println("c=" + c);
        //2.获取日历对象的某个日历字段
        System.out.println("年:" + c.get(Calendar.YEAR));
        //这里为什么要 + 1,因为Calendar 返回月的时候,是按照 0 开始编号
        System.out.println("月:" + (c.get(Calendar.MONTH) + 1));
        System.out.println("日:" + c.get(Calendar.DAY_OF_MONTH));
        System.out.println("小时:" + c.get(Calendar.HOUR_OF_DAY));
        System.out.println("分钟:" + c.get(Calendar.MINUTE));
        System.out.println("秒:" + c.get(Calendar.SECOND));
        //Calendar 没有专门的格式化方法,所以需要程序员自己来组合显示
        System.out.println(c.get(Calendar.YEAR) + "年" + (c.get(Calendar.MONTH) + 1) + "月"
                + c.get(Calendar.DAY_OF_MONTH) + "日" + " " + c.get(Calendar.DAY_OF_MONTH) + ":"
                + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND));
    }
}

第三代日期类

前面两代日期类的不足分析:

JDK 1.0中包含一个java.util.Date类,但是它的大多数方法已经在JDK 1.1引入Calendar类之后被弃用了。而Calendar也存在问题是:

  • 可变性:像日期和时间这样的类应该是不可变的。
  • 偏移性:Date中的年份是从1900开始的,而月份都从0开始
  • 格式化:格式化只对Date有用,Calendar则不行
  • 此外,它们也不是线程安全的;不能处理闰秒等(每隔2天,多出1s)。

第三代日期类常见方法

1)LocalDate(日期/年月日)LocalTime(时间/时分秒)LocalDateTime(日期时间/年月日时分秒) JDK8加入

  • LocalDate 只包含日期,可以获取日期字段
  • LocalTime 只包含时间,可以获取时候字段
  • LocalDateTime 包含日期 + 时间,可以获取日期和时间字段

在这里插入图片描述

案例演示:

public class LocalDate_ {
    public static void main(String[] args) {
        //第三代日期
        //解读:
        //1. 使用new() 返回表示当前日期时间的 对象
        LocalDateTime ldt = LocalDateTime.now();//LocalDate.new();//LocalTime.new();
        System.out.println(ldt);
        System.out.println("年=" + ldt.getYear());
        System.out.println("月=" + ldt.getMonthValue());
        System.out.println("月(英文)=" + ldt.getMonth());
        System.out.println("日=" + ldt.getDayOfMonth());
        System.out.println("小时=" + ldt.getHour());
        System.out.println("分钟=" + ldt.getMinute());
        System.out.println("秒=" + ldt.getSecond());

        LocalDate localDate = LocalDate.now();
        System.out.println("localDate=" + localDate);//年月日 yyyy-MM-dd

        LocalTime localTime = LocalTime.now();
        System.out.println("localTime=" + localTime);//时分秒.毫秒
    }
}

2)DateTimeFormatter格式日期类

类似于 SimpleDateFormat

DateTimeFormat tfd = DateTimeFormatter.ofPattern(格式);
String str = dtf.format(日期对象);

案例演示:

public class DateTimeFormatter_ {
    public static void main(String[] args) {
        LocalDateTime ldt = LocalDateTime.now();
        //使用 DateTimeFormatter 对象来进行格式化
        //创建 DateTimeFormatter对象
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH小时mm分钟ss秒");
        String format = dtf.format(ldt);
        System.out.println("格式化的日期=" + format);
    }
}

3)Instant 时间戳

类似于Date
提供了一系列和Date类转换的方法

Instant ------> Date;
Date date = Date.from(instant);
Date ------>Instant ;
Instant instant = date.toInstant();

在这里插入图片描述

案例演示:

public class Instant_ {
    public static void main(String[] args) {
        //1. 通过 静态方法 now() 获取表示当前时间戳的对象
        Instant now = Instant.now();
        System.out.println(now);
        //2. 通过 from 方法把 Instant转成 Date
        Date date = Date.from(now);
        //3. 通过 date的的toInstant() 可以把 date 转成Instant对象
        Instant instant = date.toInstant();
        System.out.println(instant);
    }
}

4)第三代日期类更多方法

  • LocalDateTime类
  • MonthDay类:检查重复事件
  • 是否是闰年
  • 增加日期的某个部分
  • 使用plus方法测试增加时间的某个部分
  • 使用minus方法测试查看一年前和一年后的日期
LocalDateTime ldt = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
//通过了 plus 和 minus方法对当前时间进行加或者减
//看看890天后,是什么时候 把 年月日-时分秒 打印出来
LocalDateTime localDateTime = ldt.plusDays(890);
System.out.println("890天后=" + dtf.format(localDateTime));

//看看在 3456分钟前是什么时候 把 年月日-时分秒 打印出来
LocalDateTime localDateTime1 = ldt.minusMinutes(3456);
System.out.println("3456分钟前日期=" + dtf.format(localDateTime1));



作业

1、编程题

(1) 将字符串中指定部分进行反转。比如将 “abcdef” 反转为 “aedcbf”

(2) 编写方法 public static String reverse(String str, int start, int end);

public class Homework01 {
    public static void main(String[] args) {
        //测试
        String str = "abcdef";
        System.out.println("---交换前---");
        System.out.println(str);
        try {
            str = reverse(str, 1, 4);
        }catch (Exception e){
            System.out.println(e.getMessage());
            System.exit(0);
        }
        System.out.println("---交换后---");
        System.out.println(str);
    }
    /*
    (1) 将字符串中指定部分进行反转。比如将 “abcdef” 反转为 “aedcbf”
    (2) 编写方法 public static String reverse(String str, int start, int end);
    思路分析:
    1. 先把方法确定 public static String reverse(String str, int start, int end);
    2. 把 String 转成 char[],因为char[] 的元素是可以交换的
    3. 代码实现
     */
    public static String reverse(String str, int start, int end){
        //对输入的参数做一个验证
        //重要的编程技巧
        //(1) 写出正确的情况
        //(2) 然后取反即可
        if (!(str != null && start >=0 && end > start && end < str.length())){
            throw new RuntimeException("参数不正确");
        }
        char[] chars = str.toCharArray();
        char temp = ' ';//交换辅助变量
        for(int i = start, j= end; i < j; i++,j--){
            temp = chars[i];
            chars[i] = chars[j];
            chars[j] = temp;
        }
        //使用chars 重新构建一个String 返回
        return new String(chars);
    }
}

2、编程题

输入用户名、密码、邮箱,如果信息录入正确,则提示注册成功,否则生成异常对象
要求:
(1)用户名长度为2或3或4
(2)密码的长度为6,要求全是数字
(3)邮箱中包含@和. 并且@在. 的前面

public class Homework02 {
    public static void main(String[] args) {
        String name = "jack";
        String pwd = "123456";
        String email = "jack@sohu.com";
        try {
            userRegister(name,pwd,email);
            System.out.println("注册成功");
        }catch (Exception e){
            System.out.println(e.getMessage());
        }

    }
    /**
     * 输入用户名、密码、邮箱,如果信息录入正确,则提示注册成功,否则生成异常对象
     * 要求:
     * (1)用户名长度为2或3或4
     * (2)密码的长度为6,要求全是数字
     * (3)邮箱中包含@和. 并且@在. 的前面
     *
     *  思路分析:
     *  1. 先编写方法名 userRegister(String name, String pwd, String email){}
     *  2. 针对 输入的内容进行校验,如果发现有问题,就抛出异常,给出提示
     *  3. 单独的写一个方法,判断 密码是否全部是数字字符 boolean
     */
    public static void userRegister(String name, String pwd, String email){
        //再加入一些效验
        if(!(name != null && pwd != null && email != null)){
            throw new RuntimeException("参数不能为空");
        }

        int userLength = name.length();
        if(!(userLength >= 2 && userLength <= 4)){
            throw new RuntimeException("用户名长度为2或3或4");
        }

        if(!(pwd.length() == 6 && isDigital(pwd))){
            throw new RuntimeException("密码的长度为6,要求全是数字");
        }

        int i = email.indexOf('@');
        int j = email.indexOf('.');
        if(!(i > 0 && i < j)){
            throw new RuntimeException("邮箱中包含@和. 并且@在. 的前面");
        }
    }

    //单独的写一个方法,判断 密码是否全部是数字字符 boolean
    public static boolean isDigital(String str){
        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if(chars[i] < '0' || chars[i] > '9'){
                return false;
            }
        }
        return true;
    }
}

3、编程题

(1)编写出java程序,输入形式为:Han shun Ping 的人名,以Ping,Han .S的形式打印出来。其中,.S是中间单纯的首字母
(2)例如输入 “Willian Jefferson Clinton”,输出形式为:Clinton,Willian .J

public class Homework03 {
    public static void main(String[] args) {
        String name = "Willian Jefferson Clinton";
        printName(name);
    }
    /**
     * (1)编写出java程序,输入形式为:Han shun Ping 的人名,以Ping,Han .S的形式打印出来。
     *      其中,.S是中间单纯的首字母
     * (2)例如输入 “Willian Jefferson Clinton”,输出形式为:Clinton,Willian .J
     *
     * 编写方法:完成输出格式要求的字符串
     * 1. 对输入的字符串进行 分割split(" ")
     * 2. 对得到的String[] 进行格式化String.format()
     * 3. 对输入的字符串进行效验
     */
    public static void printName(String str){
        if(str == null){
            System.out.println("str 不能为空");
            return;
        }

        String[] names = str.split(" ");
        if(names.length != 3){
            System.out.println("输入的字符串格式不正确");
            return;
        }
        String format = String.format("%s,%s .%c", names[2], names[0], names[1].toUpperCase(Locale.ROOT).charAt(0));
        System.out.println(format);
    }
}

4、编程题

输入字符串,判断里面有多少个大写字母,多少个小写字母,多少数字

public class Homework04 {
    public static void main(String[] args) {
        countStr("asdh1238AB$");
    }
    /**
     * 输入字符串,判断里面有多少个大写字母,多少个小写字母,多少数字
     *
     * 思路分析:
     * 1. 遍历字符串,如果 char 在 '0' - '9' 就是一个数字
     * 2. 如果 char 在 'a' - 'z' 就是一个小写字母
     * 3. 如果 char 在 'A' - 'Z' 就是一个大写字母
     * 4. 使用三个变量记录 统计结果
     */
    public static void countStr(String str){
        if(str == null){
            System.out.println("输入不能为null");
            return;
        }
        int length = str.length();
        int numCount = 0;
        int lowerCount = 0;
        int upperCount = 0;
        int otherCount = 0;
        for (int i = 0; i < length; i++) {
            if(str.charAt(i) >= '0' && str.charAt(i) <= '9'){
                numCount++;
            }else if(str.charAt(i) >= 'a' && str.charAt(i) <= 'z'){
                lowerCount++;
            }else if(str.charAt(i) >= 'A' && str.charAt(i) <= 'Z'){
                upperCount++;
            }else {
                otherCount++;
            }
        }
        System.out.println("数字有 " + numCount);
        System.out.println("小写字母有 " + lowerCount);
        System.out.println("大写字母有 " + upperCount);
        System.out.println("其他字符有 " + otherCount);
    }
}

5、试写出以下运行结果

已知Animal类有属性name,可以通过有参构造为属性赋值

class Animal{
	String name;
	public Animal(String name){
		this.name = name;
	}
}
String s1 = "zzpude";
Animal a = new Animal(s1);
Animal b = new Animal(s1);
System.out.println(a == b);//false
System.out.println(a.equals(b));//false
System.out.println(a.name == b.name);//true

String s4 = new String("zzpedu");
String s5 = "zzpedu";

System.out.println(s1 == s4);//false
System.out.println(s4 == s5);//false

String t1 = "hello" + s1;
String t2 = "hellozzpedu";
System.out.println(t1.intern() == t2);//true
public class Homework05 {
    public static void main(String[] args) {
        String s1 = "zzpedu";
        Animal a = new Animal(s1);
        Animal b = new Animal(s1);
        System.out.println(a == b);//false
        System.out.println(a.equals(b));//false
        System.out.println(a.name == b.name);//true

        String s4 = new String("zzpedu");
        String s5 = "zzpedu";

        System.out.println(s1 == s4);//false
        System.out.println(s4 == s5);//false

        String t1 = "hello" + s1;
        String t2 = "hellozzpedu";
        System.out.println(t1.intern() == t2);//true
    }
}
class Animal{
    String name;
    public Animal(String name){
        this.name = name;
    }
}
============控制台输出===============
false
false
true
false
false
true
  • 1
    点赞
  • 0
    评论
  • 6
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2021 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页

打赏作者

weixin_42469070

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

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值