第四章、第2节 常用类库

文章目录

1、泛型
1.1 概述
    泛型,即“参数化类型”。就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也
定义成参数形式(可称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。
(以下是自己对泛型的认识和总结:)
    类型形参(T):只能接收引用数据类型。
    类型实参:只能是引用数据类型,传入的参数要与之对应。
        特别的:①泛型方法的调用,实参可以是基本数据类型的变量(变量有值)传入类型形参自动变为对应
               类型(自动装箱)的引用数据类型(包装类);实参是引用数据类型,则不变。
        	   ②泛型类的使用是先创建对象,在创建对象的同时确定类型(此类型必须是引用数据类型)。
        	   ③泛型接口和抽象类的使用,子类的实现/继承要明确传入的引用数据类型,抽象方法的重写同理。
                若子类也为泛型类,则由调用者通过以上②来完成。
1.2 泛型方法

格式:

①定义:
权限修饰符 <T> 返回值声明 方法名(T a,T b,...) {
    //方法中封装的逻辑功能
    return 返回值;//返回值声明为void,略
}

②使用/调用:
方法名(实际参数);//与平时的方法调用一样,只不过被调者随传入参数类型而自动替换为对应类型(自动装箱)
               //的引用数据类型。(这是基本数据类型的变量或值的传入,经实际操作得知~)

替换原则(个人理解):
    ① 对应的基本数据类型 ——》对应的包装类(∈引用数据类型)。
    ② 引用数据类型不变。例如:String类 就为 String类,在Java中String也是引用数据类型,以及类,数组等。
    ③ 可以说泛型T是一个待指定的可接收多种引用数据类型的参数类型,参数名为对象。

泛型方法示例代码1 + 图解:

在这里插入图片描述

泛型示例代码2:

public class Sum{
	public static void main(String[] args){
		//泛型方法之可变参数求和(缺陷:只能作同类型实参的求和运算,否则产生 ClassCastException)
		//求整数集之和
		System.out.println(sum(1,2,3,4,5));			//15
		
		//求浮点数集之和
		System.out.println(sum(1.1,2.2,3.3,4.4));	//11.0
	}
	
	/**
	 * @param <T> 传入的引用数据类
	 * @param n	以数组的方式接收传入的参数
	 * @return sum和值
	 */
	public static <T> T sum(T... n) {
		Integer ISum = 0;
		Double DSum = 0.0;
		if(n[0] instanceof Integer) {		//判断传入的参数为Integer类的实例化对象
			for(int i = 0;i < n.length;i++) {
				ISum += (Integer)n[i];	//在被调之前n[i]类型不定,作运算会报错,需强转为ISum的类型
			}
		}else if(n[0] instanceof Double) {	//判断传入的参数为Double类的实例化对象
			for(int i = 0;i < n.length;i++) {
				DSum += (Double)n[i];	//同理~
			}
		}
		
		return ISum != 0 ? (T)ISum : (T)DSum;	//因返回值类型为T,需强转为T类型
	}
}
1.3 泛型类(用之多)

格式:

①定义:
class 类名<T> {
    //成员属性:权限修饰符 T 成员属性名。
    
    //成员方法:权限修饰符 T 成员方法名。
}

②使用
   -有名对象:类名<引用数据类型> 对象名 = new 类名<引用数据类型(可省略)>();
							   = new 类名<>();
   -匿名对象:基本数据类型或引用数据类型 变量或对象 = new 类名<引用数据类型(不可省)>().成员方法()或成员属性;

泛型类示例代码:

在这里插入图片描述

1.4 泛型接口

格式:

interface 接口名<T> {
    //全局常量:public static final 给定类型 全局常量名 = 初始值(必须);
    //public static final修饰(可省略),即:给定类型 全局常量名 = 初始值(必须);
    eg:
    	int NUMBER = 123321;
        String INFO = "信息";
    全局常量声明注意:
        ①数据类型不能使用非指定类型T,而是指定类型(含基本数据类型 和 引用数据类型)。
        (eg:int(Integer)long(Long)double(Double)、String... ...)
        ②全局常量名全大写,词之间用下划线连接。
---------------------------------------------------------------------------
    //抽象方法:public abstract T(或给定类型) 抽象方法名(形参列表);
    //public abstract 修饰(可省略),即:T(或给定类型) 抽象方法名(形参列表);
    eg:
       T print(T t1,T t2); 
       void say(T t);
}

泛型接口示例代码1+2:

在这里插入图片描述

//子类继承泛型父类或实现泛型接口的格式:
    ① 若子类继承泛型父类或子类实现泛型接口时,指定了泛型父类或泛型接口的类型,子类不需泛型化,即:
    	class 子类 implements/extends 泛型接口/泛型父类<指定类型> {
            
        }
    ② 若子类继承泛型父类或子类实现泛型接口时,未指定泛型父类或泛型接口,子类需泛型化,即:
        class 子类<T> implements/extends 泛型接口/泛型父类<T> {
            
        }
1.5 泛型限制类型
在使用泛型时,可以指定泛型的限定区域,/*必须是某某类的子类 或 某某接口的实现类。*/
    格式:
    	<T extends 类或接口1 & 接口2>
    
具体使用格式:
    class 类名<T extends 类或接口1 & 接口2> {
        T name;				//name是未实例化的对象(不能被直接使用,否则产生空指针异常)
        
        T say(){
            return name;	//调用处返回一个name对象(基于此可实现链式编程)
        }
    }

示例代码:

public class Demo1{
	public static void main(String[] args){
        //Intraduce1<Fish> i1 = new Intraduce1<>();	//(×)传入的类型已指定,必须是Bird类型
		Intraduce1<Bird> i1 = new Intraduce1<>();
		//i.name.name = "企鹅";	//NullPointerException(空指针异常!!!)
		//在使用Intraduce内的成员属性时,必须先实例化一个对象并赋给该成员属性(否则产生空指针异常)
		//对象如同C语言中的指针,而此对象用于指向 new 所开辟的存放Bird成员属性和方法的空间的地址。
		i1.name = new Bird();	//i.name为Bird对象
		i1.name.name = "企鹅";   //相当于,Bird对象.name = "企鹅";
		i1.name.age = 9;		//Bird对象.age = 9;
		
		//链式编程:调用方法①返回一个对象,再调用方法②返回一个对象,再... ...,最后一个返回空。
		i1.say().say();			//先执行i.say()并返回Bird对象,接着执行Bird对象.say();(链式编程)
		
        //Intraduce2<Bird> i2 = new Intraduce2<>();	//(×)同理,必须是Fish类型
		Intraduce2<Fish> i2 = new Intraduce2<>();
		i2.name = new Fish();
		i2.name.name = "海豚";
		i2.name.age = 23;
		
		i2.say().say();
	}
}

class Bird {
	String name;
	int age;
	
	public void say() {
		System.out.println("我是" + name + ",今年" + age + "岁。");
	}
}

class Fish {
	String name;
	int age;
	
	public void say() {
		System.out.println("我是" + name + ",今年" + age + "岁。");
	}
}

//限制在创建对象的时候,指定的引用类型必须是Bird类型
class Intraduce1<T extends Bird> {
	T name;	//name是未实例化Bird对象(不能直接使用,否则产生空指针异常)
	
	public T say() {
		System.out.print("自我介绍:");
		return name;	//向调用者返回Bird对象
	}
}

//限制在创建对象的时候,指定的引用类型必须是Fish类型
class Intraduce2<T extends Fish> {
	T name;	//name是未实例化Fish对象(不能被直接使用,否则报空指针异常)
	
	public T say() {
		System.out.print("自我介绍:");
		return name;	//向调用者返回Fish对象
	}
}
1.6 泛型中的通配符 ?
类型通配符是使用 ? 替代方法具体的类型实参。
    
    <? extends Parent> //指定了泛型类型的上届(仅为Parent及Parent之下的所有子孙类,非父类)
    <? super Child>	   //指定了泛型类型的下届(仅为Child及Child之上至Object类的所有类,非子类)
    <?>				   //指定了没有限制的泛型类型(可以是任意存在的引用数据类型 为 泛型实参)
    
具体使用格式:
    类名<? extends 给定类名> 对象名 = new 类名<给定类名及其上届类名>(构造器实参列表);
	类名<? super 给定类名> 对象名 = new 类名<给定类名及其下届类名>(构造器实参列表);
	类名<?> 对象名 = new 类名<任意存在的引用数据类型>(构造器实参列表);

示例代码:

public class Demo2 {

	public static void main(String[] args) {
		//指定泛型的上届为Person(含Person)
										 //Person超过了Student的上届,报错~
		//Student<? extends Student> s = new Student<Person>("小明",21,"爪哇岛");(×)
		Student<? extends Person> s = new Student<Person>("小明",21,"爪哇岛");
		s.say();
		
		//指定泛型的下届为Animal(含Animal)
										 //Dog超过了Animal的下届,报错~
		//Dog<? super Animal> d = new Dog<Dog>("泰迪",7,"夏威夷");	(×)
		Dog<? super Animal> d = new Dog<Biology>("泰迪",7,"夏威夷");
		d.say();
		
		//指定没有限制的泛型类型(泛型实参可以是任意存在的引用数据类型)
		Bird<?> b = new Bird<Error>("企鹅",21,"南极");
		b.say();
	}

}
//生物类
class Biology {
	private String name;
	private int age;
	private String addr;
	
	public Biology() {}
	
	public Biology(String name, int age, String addr) {
		super();
		this.name = name;
		this.age = age;
		this.addr = addr;
	}

	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 String getAddr() {
		return addr;
	}

	public void setAddr(String addr) {
		this.addr = addr;
	}
}

class Person extends Biology {
	public Person() {}
	
	public Person(String name, int age, String addr) {
		super(name, age, addr);
	}

	public void say() {
		System.out.println("自我介绍,我是" + getName() + ",今年" + getAge() + "岁,来自" + getAddr());
	}
}

class Animal extends Biology {
	public Animal() {}
	
	public Animal(String name, int age, String addr) {
		super(name, age, addr);
	}

	public void say() {
		System.out.println("自我介绍,我是" + getName() + ",今年" + getAge() + "岁,来自" + getAddr());
	}
}

class Student<T> extends Person {
	public Student() {}

	public Student(String name, int age, String addr) {
		super(name, age, addr);
	}
}

class Dog<T> extends Animal {
	public Dog() {}

	public Dog(String name, int age, String addr) {
		super(name, age, addr);
	}
}

class Bird<T> extends Animal {
	public Bird() {}

	public Bird(String name, int age, String addr) {
		super(name, age, addr);
	}
}

作用:

1、提高代码复用率。
2、泛型中的类型在使用时指定,不需要强制类型转换(类型安全,编译器会检查类型)

注意:

在编译之后程序会采取去泛型化的措施:
	- 在Java中的泛型,只在编译阶段有效。
	- 泛型信息不会进入到运行时阶段。

2、常用类库(具体参考Java API手册)
/**
 * 对于常用类库的学习:它是一个给定的工具集,建议多用、多练、研究并总结自己的使用心得和技巧。
 *
 * 在这些类中大多有一个共同的特点兼优点:
 *    类中的方法均被static修饰,可直接用“类名”调用,而不用额外创建对象调用。
 */
2.1 java.util.Objects
1、检查传入的索引是否越界【数组相关】(不常用)
    • (1) public static int checkFromIndexSize(int fromIndex, int size, int length);

      描述:检查子范围 [fromIndex , fromIndex + size) 是否在 [0 , length) 范围界限内,

      是,return fromIndext ;否, 抛出索引越界异常。


    • (2) public static int checkFromToIndex(int fromIndex, int toIndex, int length);

      描述:检查子范围 [fromIndex , toIndex) 是否在 [0 , length) 范围界限内,

      是,return fromIndext ; 否,抛出索引越界异常。


    • (3) public static int checkIndex(int index, int length);

      描述:检查子范围 index 是否在 [0 , length) 范围界限内,

      是,return Index ; 否,抛出索引越界异常。


      示例代码

      import java.util.Objects;
      //checkFromIndexSize()、checkFromToIndex()、checkIndex()的使用。
      public class Demo1 {
      	public static void main(String[] args) {
      		int[] arr = {1,2,3,4,5,6,7,8,9};
      		int fromIndex,index;
      		/**
      		 * static int checkFromIndexSize(int fromIndex,  int size, int length)
      		 */
      		//1-1、检查子范围[3,3+5)是否在[0,8)范围界限内。
      		try {
      			fromIndex = Objects.checkFromIndexSize(3, 5, 8);
      			System.out.println("子范围[3,3+5)在[0,8)范围界限内,并返回:" + fromIndex);
      		}catch(IndexOutOfBoundsException e) {
      			System.out.println("产生异常,说明[3,3+5)不全在[0,8)范围界限内");
      		}
      		//1-2、检查子范围[2,2+6)是否在arr数组下标范围界限内。
      		try {
      			fromIndex = Objects.checkFromIndexSize(2, 6, arr.length);
      			System.out.println("子范围[2,2+6)在arr数组下标范围界限内,并返回:" + fromIndex);
      		}catch(IndexOutOfBoundsException e) {
      			System.out.println("产生异常,说明[2,2+6)不全在arr数组下标范围界限内");
      		}
      		/**
      		 * static int checkFromToIndex(int fromIndex, int toIndex, int length)
      		 */
      		//2-1、检查子范围[3,5)是否在[0,4)范围界限内。
      		try {
      			fromIndex = Objects.checkFromToIndex(3, 5, 4);
      			System.out.println("子范围[3,5)在[0,4)范围界限内,并返回:" + fromIndex);
      		}catch(IndexOutOfBoundsException e) {
      			System.out.println("产生异常,说明[3,5)不全在[0,4)范围界限内");
      		}
      		//2-2、检查子范围[6,9)是否在arr数组下标范围界限内。
      		try {
      			fromIndex = Objects.checkFromToIndex(3, 5, arr.length);
      			System.out.println("子范围[6,9)在arr数组下标范围界限内,并返回:" + fromIndex);
      		}catch(IndexOutOfBoundsException e) {
      			System.out.println("产生异常,说明[6,9)不全在arr数组下标范围界限内");
      		}
      		/**
      		 * static int checkIndex(int index, int length)
      		 */
      		//3-1、检查3是否在[0,5)范围界限内。
      		try {
      			index = Objects.checkIndex(3, 5);
      			System.out.println("3在[0,5)范围界限内,并返回:" + index);
      		}catch(IndexOutOfBoundsException e) {
      			System.out.println("产生异常,说明3不全在[0,5)范围界限内");
      		}
      		//3-2、检查4是否在arr数组下标范围界限内。
      		try {
      			index = Objects.checkIndex(4, arr.length);
      			System.out.println("4在arr数组下标范围界限内,并返回:" + index);
      		}catch(IndexOutOfBoundsException e) {
      			System.out.println("产生异常,说明4不全在arr数组下标范围界限内");
      		}
      	}
      }
      


2、compare()
    • (1) public static <T> int compare(T a,T b,Comparetor<? super T> c);

      描述:如果 a==b,返回0;否则,返回c.compare(a,b)(并非调用自己)


      示例代码:

      //略。
      


3、equals():比较两个值是否相同
    • (1) public static boolean deepEquals(Object a, Object b);

      描述:如果a与b深层相等,且彼此false或其他,返回true。

      如果a与b都是数组,则使用Arrays.deepEquals0(a, b)中的算法来确定相等性。


    • (2) public static boolean equalse(Object a, Object b);

      描述:如果a与b相等,且彼此false或其他,返回true;否则,返回false。


      示例代码:

      import java.util.Objects;
      //deepEquals()、equals()的使用与区别。
      public class Main {
          public static void main(String[] args) {
              boolean b;
              
              int[] arr1 = {1,3,4,5};
              int[] arr2 = {1,3,5,4};
              int[] arr3 = {1,3,5,4};
              
              Person p1 = new Person("小明",23);
              Person p2 = new Person("小明",23);
              Person p3 = null;
              
              //注:Person类中已重写Object类的equals()方法
              b = Objects.deepEquals(arr1,arr2);	//b = false
              b = Objects.deepEquals(arr2,arr3);	//b = true
              b = Objects.deepEquals(p1,p2);		//b = true
              b = Objects.deepEquals(p2,p3);		//b = false
              
              b = Objects.equals(arr2,arr3);	//b = false(缺陷:Objects类中的equals()不能判断数组)
              b = Objects.equals(p1,p2);		//b = true
              b = Objects.equals(p2,p3);		//b = false
          }
      }
      


4、hash值的生成
    • (1) public static int hash(Object... values);

      描述:为一系列输入值生成哈希码,输入的值以数组的方式接收并调用

      Arrays.hashCode(Object a[])对数组进行哈希处理。

      警告:提供单个对象引用时,返回值 != 该对象引用的哈希码。可通过hashCode()来计算。


    • (2) public static int hashCode(Object o);

      描述:返回非空参数的哈希码,空参数的哈希码为0。


      示例代码:

      import java.util.Objects;
      //hash()、hashCode()的使用。
      //注意:null的哈希值为0,整数类型和字符类型的哈希值为本身。
      public class Main {
          public static void main(String[] args) {
              byte b = 0;
              float f = 1.2F;
              int hashCodeValue;
      
              //1、hashCode()的正确用,传入一个参数。
              hashCodeValue = Objects.hashCode(null); //0
              System.out.println(hashCodeValue);
      
              hashCodeValue = Objects.hashCode(b);    //0
              System.out.println(hashCodeValue);
      
              hashCodeValue = Objects.hashCode('0');  //48(字符0的ASCII码为48)
              System.out.println(hashCodeValue);
      
              hashCodeValue = Objects.hashCode(f);    //1067030938
              System.out.println(hashCodeValue);
      
              //2、hash()的错误用法。
              hashCodeValue = Objects.hash(0);    	//31,比hashCode(0)多31
              System.out.println(hashCodeValue);
      
              //3、hash()的正确用法,传入多个参数。
              hashCodeValue = Objects.hash(0,1,3);
              System.out.println(hashCodeValue);
      
              hashCodeValue = Objects.hash(b,f);
              System.out.println(hashCodeValue);
      
              //4、hashCod()在对象中的使用。
              Person p1 = new Person("小张",23);
              Person p2 = new Person("小张",23);
              Person p3 = new Person("小李",25);
              //注意:在Person类中需重写hashCode()方法后,p1和p2的哈希码值才一样。
              System.out.println("p1 hashCode:" + Objects.hashCode(p1));  //23403783
              System.out.println("p2 haseCode:" + Objects.hashCode(p2));  //23403783
              System.out.println("p3 haseCode:" + Objects.hashCode(p3));  //23468699
          }
      }
      


5、判断一个对象是否为null
    • (1) public static boolean isNull(Object obj);

      描述:如果obj = null,返回true;相反,返回false。


    • (2) public static boolean nonNull(Object obj);

      描述:如果obj != null,返回true;相反,返回false。


    • (3) public static <T> T requireNonNull(T obj);

      描述:检查指定的对象(obj)不为空,为空抛出NullPointerException。


    • (4) public static <T> T requireNonNull(T obj, String message);

      描述:检查指定的对象(obj)不为空,为空抛出自定义(message)的NullPointerException。

      message:用于描述异常信息


    • (5) public static <T> T requireNonNull(T obj,Supplier<String> messageSupplier);

      描述:检查指定的对象(obj)不为空,为空抛出自定义(message)的NullPointerException。

      messageSupplier:?。。。


    • (6) public static<T> T requireNonNullElse(T obj,T defaultObj);

      描述:if( obj非null ),返回obj;else,返回defaultObj。

      defaultObj:默认参数,可自定义。

      注意:两个参数不能同时为null,否则飘红出错


    • (7) public static<T> T requireNonNullElseGet(T obj,Supplier<? exteds T> supplier);

      描述:if( obj非null ),返回obj;else,返回supplier.get() 。

      注意:两个参数不能同时为null,否则飘红报错



6、toString():转字符串
    • (1) public static String toString(Object o);

      描述:非null,返回调用结果的字符串表示形式;相反,返回null。

      创建类时:建议重写toString()方法,用于返回自己需要的字符串信息。

    • (2) public static Stirng toString(Object o, String nullDefault);

      描述:如果o != null,返回o.toString()【调用上一个方法】的结果;否则,返回nullDefault。

      创建类时:同理,建议重写toString()方法,用于返回自己需要的字符串信息。



2.2 java.lang.Math
1、求绝对值
    • Math.abs(a); //求|a|:a的类型 ∈ {int, long, float, double};
2、找最大值、最小值
    • Math.max(a,b); //(a,b)max
    • Math.min(a,b); //(a,b)min:a,b的类型同等 ∈ {int, long, float, double};
3、四舍五入(五入:往前增长,使补全取整)【常用】
    • Math.round(10.5); //11
    • Math.round(-10.2); //-10
    • Math.round(-10.5); //-10:“五入”有增长趋势,故:-10.5入了就变成了-10。
    • Math.round(-10.6); //-11
    • (正数中:≥ 5 的“入”,使补全取整;相反,舍弃。)
    • (负数中:≥ -5 的“入”,增长取整;相反,舍弃(-1)。)
4、返回 ≤ 参数的最大整数
    • Math.floor(3.5); //3.0
    • Math.floor(-3.5); //4.0
5、返回 ≥ 参数的最小整数
    • Math.ceil(3.5); //4.0
    • Math.ceil(-3.5); //-3.0
… …

提示若程序中涉及到算术运算,首先想到的是Math类,因Math类提供了丰富的运算方法。



2.3 java.util.Arrays
1、sort():双轴快速排序
    • Arrays.sort(arr); //对数组arr进行升序排列
2、binarySearch():二分查找
    • findIndex = binarySearch(arr,key); //在arr数组中查找key,并将对应下标返回给findIndex

注意二分查找仅适用于有序排列的线性表中查找指定的那一个元素。其线性表可以是,数组,链表… …

3、compare():数组间的比较(两者)
    • compare(a,b); //比较数组a和数组b对应元素及长度是否相同

      • 先判断a和b的下标在[0 , Math.min(a.length , b.length))区间对应元素是否相同:
      • ① 不同,若a[i] > b[i],return 1;相反,return -1;(i 从[0 , Math.min(a.length , b.length))区间遍历判断)
      • ② 相同,分三步走:
        • <1> 若a.length > b.length,return (a.length - b.length); 【正数】;
        • <2> 若a.length < b.length,return (a.length - b.length); 【负数】;
        • <3> 若a.length = b.length,return 0。

      示例代码:

      int[] a1 = {1,2,3};
      int[] b1 = {1,2,3};
      System.out.println(Arrays.compare(a1,b1));	//0
      
      int[] a2 = {1,2,4};
      int[] b2 = {1,2,3,4,5};
      System.out.println(Arrays.compare(a2,b2));	//1
      System.out.println(Arrays.compare(b2,a2));	//-1
      
      int[] a3 = {1,2};
      int[] b3 = {1,2,3,4,5};
      System.out.println(Arrays.compare(a3,b3));	//-3
      System.out.println(Arrays.compare(b3,a3));	//3
      
4、equals():比较俩数组对应元素值是否相同
    • equals(a,b); //比较数组a和数组b中对应元素是否相同,相同,return true;相反,return false
5、toString():将数组转字符串
    • toString(arr); //返回 数组arr元素以‘[]’包裹‘,’分隔的字符串

      示例代码:

      int[] arr = {1,2,3,4,5};
      String s = Arrays.toString(arr);
      System.out.println(s);	//[1, 2, 3, 4, 5]
      
6、copyOf():对数组进行动态扩容
    • arr = copyOf(arr,arr.length + n); //将数组arr的长度扩充n个单位长度

      示例代码:

      byte[] arr = {1,2,3};
      System.out.println(Arrays.toString(arr));	//[1, 2, 3]
      arr = Arrays.copyOf(arr,arr.length + 3);	//将数组arr的容量扩充3个byte类型的长度
      System.out.println(Arrays.toString(arr));	//[1, 2, 3, 0, 0, 0]
      
… …

提示程序中涉及与数组相关的,参考Java API手册中Arrays类给定的方法。



2.4 java.math.BigDecimal

示例:

System.out.println(0.1 + 0.2);	//0.30000000000000004(精度缺失,有误差!!!)
/**
 *    在金融行业和银行的管理系统中出现以上误差,经无限放大后,将会产生不可估量的后果~。
 * 为了避免运算过程中精度的缺失,Java提供了BigDecimal类,借助BigDecimal类中的方法,
 * 可以规避这类精度缺失的问题。
 */
BigDecimal b1 = new BigDecimal("0.1");
BigDecimal b2 = new BigDecimal("0.2");
BigDecimal b3 = b1.add(b2);
System.out.println(b3);	//0.3(确保了精度)
1、常用构造器
    • public BigDecimal(String val); //引用时需创建对象,并向构造器传入字符串化的数字初始化。
2、高精度的算术运算

​ 在进行运算之前首先创建BigDecimal类的对象,在创建对象的同时传入需要计算的参数,并将参数字符串化。再结合创建的对象调用BigDecimal类中的算术运算方法完成运算。

    • 加:public BigDecimal add(BigDecimal augend);

      BigDecimal b1 = new BigDecimal("0.01");
      BigDecimal b2 = new BigDecimal("0.02");
      BigDecimal b3 = b1.add(b2);
      System.out.println("0.01 + 0.02 = " + b3);//0.01 + 0.02 = 0.03(确保了精度)
      
    • 减:public BigDecimal subtract(BigDecimal subtrahend);

      BigDecimal b1 = new BigDecimal("0.01");
      BigDecimal b2 = new BigDecimal("0.02");
      BigDecimal b3 = b1.subtract(b2);
      System.out.println("0.01 - 0.02 = " + b3);//0.01 - 0.02 = -0.01(确保了精度)
      
    • 乘:public BigDecimal multiply(BigDecimal multiplicand)

      BigDecimal b1 = new BigDecimal("0.01");
      BigDecimal b2 = new BigDecimal("0.02");
      BigDecimal b3 = b1.multiply(b2);
      System.out.println("0.01 * 0.02 = " + b3);//0.01 * 0.02 = 0.0002(确保了精度)
      
    • 除:public BigDecimal divide(BigDecimal divisor)

      BigDecimal b1 = new BigDecimal("0.01");
      BigDecimal b2 = new BigDecimal("0.02");
      BigDecimal b3 = b1.divide(b2);
      System.out.println("0.01 / 0.02 = " + b3);//0.01 / 0.02 = 0.5(确保了精度)
      
      • 注意当除不尽的时候,会抛出算术异常。
        • 解决方案对divide()传入3个参数,即:(除数,小数位数,舍入规则)
      BigDecimal b1 = new BigDecimal("2");
      BigDecimal b2 = new BigDecimal("3");
      BigDecimal b3 = b1.divide(b2,3,RoundingMode.HALF_UP);	//四舍五入保留3位
      System.out.println("2 / 3 = " + b3);//2 / 3 = 0.667(确保了除不尽产生异常)
      
3、获取BigDecimal对象的基本数据类型值

注意:对应类型的匹配要一致~

    • 获取整形数:int i = b.intValue(); //将BigDecimal对象b转为int类型赋给变量i
    • 获取浮点数:float f = b.floatValue();
    • … …

提示在涉及高精度计算的时候,建议使用Java API文档查阅BigDecimal类中的方法。

补充:与BigDecimal类对应的有BigInteger类,据悉它可以支持任意精度的整数。



2.5 java.util.Date

Date类表示特定的时刻,精度为毫秒。

缺陷:

Date类允许将日期解释为:年,月,日,时,分,秒; 也允许格式化和解析日期字符串。但都不适合国际化。

1、常用构造器
    • public Date(); //表示当前时间,此时此刻(毫秒级)

    示例:

    Date date = new Date();
    //传入任何对象打印,都是在打印自身的toString()方法。
    System.out.println(date);	//Mon Apr 12 10:00:10 CST 2021
    
    • public Date(long date); //得到格林尼治时间到传入一个毫秒数的时间,用于指定过去和未来

    示例:

    /**
     * 传入0ms,可得到当时的格林尼治时间:Thu Jan 01 00:00:00 GMT 1970
     *		          当时的东八区时间:Thu Jan 01 08:00:00 CST 1970
     * 由于现在位于东八区,东八区的时间比格林尼治时间快8小时。
     */
    System.out.println(new Date(0));			//Thu Jan 01 08:00:00 CST 1970
    /**
     * 传入24*60*60*1000ms,可得到格林尼治时间第二天所对应的东八区的时间。
     */
    System.out.println(new Date(24*60*60*1000));//Fri Jan 02 08:00:00 CST 1970
    
2、常用的方法
    • public long getTime(); //获取当前时间毫秒数

    示例

    long time;
    Date date = new Date();		//获取当前时间
    time = date.getTime();		//获取当前时间(ms)
    System.out.println(time);				//1618205804691 ms
    System.out.println(new Date(time));		//Mon Apr 12 13:36:44 CST 2021
    time = date.getTime() - (24*60*60*1000);//将获取的当前时间 - 24h
    System.out.println(time);				//1618119404691
    System.out.println(new Date(time));		//Sun Apr 11 13:36:44 CST 2021
    
    • 时间的比较(之前/之后):
      • date.after(Date when); //比较日期(date)是否在当前日期之后,是,返回true;否,返回false。
      • date.befor(Date when); //比较日期(date)是否在当前日期之前,是,返回true;否,返回false。
    • public Object clone(); //返回对象的副本
    • public int compareTo(Date anotherDate); //对两个日期进行比较
      • date1.compareTo(data2);
        • 若date1 > date2,return 1;
        • 若date1 == date2,return 0;
        • 若date1 < date2,return -1。
    • public boolean equals(Object obj);//比较两个日期是否相等
      • date1.equals(date2);
        • 若date1 == date2,return true;
        • 若date1 != date2,return false;
    • public static Date from(Instant instant); //从Instant对象获得Date的实例

    • public Instant toInstant(); //将Date类的对象转为Instant类的对象(与Date不同,Instant的精度为纳秒)

    使用示例

    //Instant ————》 Date
    Instant instant1 = Instant.now();
    Date date1 = Date.from(instant1);
    System.out.println("instant1:" + instant1);	//instant1:2021-04-12T08:03:15.165230700Z
    System.out.println("date1:" + date1);		//date1:Mon Apr 12 16:03:15 CST 2021
    
    //Date ————》 Instant
    Date date2 = new Date();
    Instant instant2 = date2.toInstant();
    System.out.println("date2:" + date2);		//date2:Mon Apr 12 16:03:15 CST 2021
    System.out.println("instant2:" + instant2);	//instant2:2021-04-12T08:03:15.288Z
    
    • public int hashCode(); //返回对象的哈希值
    • **public String toString(); //将Date对象转为"dow mon dd hh:mm:ss zzz yyyy"形式的字符串


2.6 java.text.DateFormat

DateFormat类用于日期的格式化和解析,是一个比较好用的工具,日期和时间的格式可以灵活地自定义。

注意DateFormat是一个抽象类,需借助子类SimpleDateFormat间接引用DateFormat中的方法。

1、常用方法
    • (1) public final String format(Date date);//将Date格式化为日期时间字符串
    • (2) public Date parse(String source); //从给定字符串的开头解析文本以生成日期

    示例代码

    /**
     * y : 年
     * M : 月
     * d : 日
     * H : 时
     * m : 分
     * s : 秒
     * 。。。 。。。,关于其他日期和时间模式的字符串参见以下表2-1所示。
     * 注:一个字符代表一位时间数
     * 比较合理的格式字符串:"yyyy-MM-dd HH:mm:ss"
     */
    //用于格式化日期的类
    SimpleDateFormat simp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    //format():用于将new Date()对象转为字符串"yyyy-MM-dd HH:mm:ss"的格式。
    String text = simp.format(new Date());
    System.out.println("当前时间:" + text);					//当前时间:2021-04-12 18:49:23
    
    //以下parse():用于将"1970-1-1 08:00:00"日期字符串转换为Date对象
    //注意:一定要符合SimpleDateFormat创建的格式“ "yyyy-MM-dd HH:mm:ss" ”
    //借助parse()方法计算一个人从出生到现在经历的天数。
    Date date = simp.parse("1970-01-01 08:00:00");	//生日
    long day = ((new Date().getTime() - date.getTime())/1000/60/60/24); //计算天数
    System.out.println("从出生到现在共经历了" + day + "天。");	//从出生到现在共经历了18729天。
    
    表2-1 日期和时间模式的字符串

在这里插入图片描述



2.7 java.util.Calender

Calender用于日期和时间字段之间进行转换,Calendar类解决了Date类在时间上不能夸国际化的问题。

注意:Calender是一个抽象类,不能直接创建对象,但Canlendar提供了一个类方法getInstance(),用于获取此类型的通用对象。

1、Calendar类方法(被static修饰的方法)
    • Calendar c = Calendar.getInstance(); //通过Calendar.getInstance(),返回Calendar类的对象
2、常用的两个方法
    • (1) public int get(int field); //通过传入一个常量字段获取,返回一个字段之意的时间值
    • (2) public void set(int field, int value); //通过传入的常量字段设置相应的时间值,此值仅设置运行中的程序
3、另外两个比较实用方法
    • (1) public final Date getTime(); //获取日历时间,返回一个Date对象

      • 注意:在计算机中,月份:0~11的范围(0表示一月,11表示十二月);其他待定。
    • (2) public int getActualMaximum(int field); //获取对应字段的最大值

4、计算日历的方法(加、减、乘、除)
    • public void add(int field, int amount); //根据对应字段,对时间进行加运算
    • 其他同理
5、常用常量字段(通过类名Calendar调用)
    • (1) YEAR:调用年份的值;
    • (2) MONTH:调用月份的值;
    • (3) WEEK_OF_YEAR:该年第几周;
    • (4) WEEK_OF_MONTH:该月第几周;
    • 。。。 。。。

示例代码

public class Main {

    public static void main(String[] args) {
        Calendar c = Calendar.getInstance();
        int year = c.get(Calendar.YEAR);
        System.out.println("设置前:" + year + "年");
        c.set(Calendar.YEAR,2025);
        year = c.get(Calendar.YEAR);
        System.out.println("设置后:" + year + "年");

        Date d = c.getTime();
        System.out.println(d);

        int maxDay = c.getActualMaximum(Calendar.DAY_OF_YEAR);
        System.out.println(year + "年最大天数:" + maxDay + "天");

        c.add(Calendar.YEAR,-5);
        year = c.get(Calendar.YEAR);
        System.out.println("加了后:" + year + "年");
    }
}
----------------------------------------------------------------------------
打印结果:
    设置前:2021年
    设置后:2025年
    Mon Apr 14 23:38:19 CST 2025
    2025年最大天数:365天
    加了后:2020


2.8 java.lang.System

System类提供了大量的静态方法及属性。

1、常用字段
    • in //“标准”输入流。

      • eg:
            String input = new Scanner(System.in).nextLine(); //从键盘输入一个字符串
        
    • out //“标准”输出流。

      • eg:
            System.out.println("Hello world~");
        
2、方法(不常用,在测试时会用上)
    • (1) System.gc(); //运行垃圾回收器,回收堆内存不再引用的堆内存(即没有对象指向它)

      • eg:
        	String s = new String("Tom");	//为s对象在堆中开辟一段堆内存,存放字符串“Tom”
        	System.out.println(s);	//Tom
        	s = null;
        	System.gc();	//执行垃圾回收器,回收s不再引用的堆内存
        	System.out.println(s);	//null
        
    • (2) System.exit(int status); //用于终止当前运行的Java虚拟机。

      • Runtime.getRuntime().exit(int status); //与System.exit()类似。
    • (3) System.arraycopy(Object src, int srcPos,Object dest, int destPos,int length);

      • //将指定原数组src中指定位置srcPos开始 复制 到目标数组dest从指定位置destPos粘贴length个元素。


3、String(很重要!)

String类表示字符串。在Java中,所有用" "扩起来的字符串都是String类的实例(此实例指对象)。

特点:String是不可变的字符序列,它们的值创建后无法更改。若俩字符串一样,则共享其中一个;通过new关键字创建的则各自占用一片空间。

3.1 常用构造方法
    • (1) String(byte[] bytes,String charsetName); //传字节数组创建指定编码(与前端字符编码相关)
    • (2) String(byte[] bytes); //传字节数组创建不指定编码
    • (3) String(char[] value); //传char数组创建不指定编码
    • 。。。 。。。

    示例代码

    byte[] b1 = {48,56,97,98,79,72};
    String str = "UTF-8"; 			//字符编码(例:ASCII、GB3212、GBK... ...)
    String str1 = new String(b1,str);
    System.out.println(str1);		//08abOH
    
    byte[] b2 = {48,49,50,51,52};
    String str2 = new String(b);
    System.out.println(str2);		//01234
    
    char[] c1 = {'a','b','c','d'};
    String str3 = new String(c1);
    System.out.println(str3);		//abcd
    
3.2 常用方法(都很重要)
    • (1) charAt(int index); //返回指定索引处的char值

      • System.out.println("1234".charAt(2));	//打印"1234"索引下标2的字符 ——》3
        
    • (2) codePointAt(int index); //返回指定索引处的字符Unicode值

    • codePointBefore(int index); //返回指定索引之前的字符Unicode值

    • codePointCount(int beginIndex,int endIndex); //返回endIndex下标与beginIndex下标的Unicode之差

      • String str = "abdecf";
        System.out.println(str.codePointAt(0));		//打印str索引下标为0的Unicode值 ——》97
        System.out.println(str.codePointBefore(2));	//打印str索引下标为2之前的Unicode值 ——》98
        System.out.println(str.codePointCount(1,4));//打印str索引下标为4 - str索引下标为1的Unicode值 ——》1
        
    • (3) compareTo(String anotherString); //按字典顺序比较两字符串

      • int c = "abc".compareTo("abc"); //c = 0
        c = "abc".compareTo("123");		//因字符a与字符1不同,c = 'a' - '1' = 48
        c = "012".compareTo("abc");		//同理,c = '0' - 'a' = -48
        
    • compareToIgnoreCase(String str); //按字典顺序比较两字符串,忽略大小写

      • int c = "Abc".compareToIgnoreCase("aBc"); //c = 0
        c = "Abc".compareToIgnoreCase("123");	  //c = 'a' - '1' = 48(忽略大小写默认均为小写Unicode值)
        c = "012".compareToIgnoreCase("AbC");	  //c = '0' - 'a' = -49(同理)
        
    • (4) concat(String str); //将指定str字符串连接到此字符串末尾(建议用便捷的“+”号)

      • String s = "123".concat("456");	//s = "123456"
        相当于:
        s = "123" + "456";	//s = "123456"
        
    • contains(CharSequence s); //当且仅当此字符串包含指定的char值序列时,才返回true

      • //CharSequence是String的父接口,可接收字符串。
        char[] c = {49,50,51};	//对应字符为1,2,3
        boolean b1 = "123".contains(String.valueOf(c));	//b1 = true
        boolean b2 = "012".contains(String.valueOf(c)); //b2 = false
        boolean b3 = "234".contains("2");	//b3 = true ("2"包含在"234")
        boolean b4 = "123".contains("0");	//b4 = false
        
    • contentEquals(charSequence cs); //若此字符串为指定的charSequence(全等),返回true

      • char[] c = {48,49,50};	//对应字符为0,1,2
        boolean b1 = "012".contentEquals(String.valueOf(c)); //b1 = true
        boolean b2 = "012".contentEquals("012");	//b2 = true
        boolean b3 = "123".contentEquals("1");	//b3 = false(非全等)
        
    • contentEquals(StringBuffer sb); //若此字符串为指定的StringBuffer(全等),返回true

      • StringBuffer ss = new StringBuffer("123");
        boolean b1 = "123".contentEquals(ss);	//b1 = true
        boolean b2 = "12".contentEquals(ss);	//b2 = false
        
    • (5) copyValueOf(char[] data); //相当于valueOf(char[])

      • char[] c = {'a','B','c'};
        //将数组c所有元素变成字符串拷贝给s
        String s = String.copyValueOf(c);		//s = "aBc"
        
    • copyValueOf(char[] data,int offset,int count); //相当于valueOf(char[],int,int)

      • char[] c = {'1','2','3','4','5','6','7'};
        //将数组c的2号下标开始数3个字符拷贝给s
        String s = String.copyValueOf(c,2,3);	//s = "345"
        
    • (6) endsWith(String suffix); //测试此字符串是否以指定的后缀结尾,是,返回true;否,返回false

      • String s = "HelloWorld.java";
        String suffix = ".java";
        boolean b1 = s.endsWith(suffix); //b1 = true
        boolean b2 = s.endsWith(".txt"); //b2 = false
        
    • (7) equals(Object anObject); //将此字符串与指定的对象进行比较

      • String s = "hello";
        Object o = "hello";
        boolean b1 = s.equals(o);		//b1 = true
        boolean b2 = s.equals("he");	//b2 = true
        
    • equalsIgnoreCase(String anotherString); //将此字符串与另一个字符串比较,忽略大小写

      • String s1 = "ABCd";
        String s2 = "abcd";
        boolean b1 = s1.equalsIgnoreCase(s2);	//b1 = true(因忽略大小写)
        boolean b2 = s1.equalsIgnoreCase("A");	//b2 = false
        
    • (8) format(String format,Object... args); //使用指定的格式字符串和参数返回格式化字符串

      • format:指定的格式字符串,例:%d,%s… …

      • args:参数

      • int a = 10,b = 23;
        String sum1 = String.format("%d",a+b);			//sum1 = "33"
        String sum2 = String.format("%f",1.2 + 3.3);	//sum2 = "4.5"
        String sum3 = String.format("%f%%",35);			//sum3 = 35%
        System.out.println(String.format("%s","he"));	//he
        
    • format(Locale l,String format,Object... args); //使用指定的语言环境,格式化字符串和参数返回格式化的字符串

      • String chinaFloat = String.format(Locale.CHINA,"%f",123.456);
        System.out.println(chinaFloat);										//123.456000(中国)
        String italianFloat = String.format(Locale.ITALIAN,"%f",123.456);
        System.out.println(italianFloat);									//123,456000(意大利)
        String germanFloat = String.format(Locale.GERMAN,"%f",123.456);
        System.out.println(germanFloat);									//123,456000(德国)
        说明:根据不同国家或语言,其显示浮点数的小数点不同(格式不同),通过此方式可实现跨国际化。
        
      转换类型详细说明示例
      %s字符串类型“字符串”
      %c字符类型‘A’
      %b布尔类型true / false
      %d整数类型(十进制)79
      %x整数类型(十六进制)3F
      %o整数类型(八进制)73
      %f浮点类型123.45
      %a浮点数(十六进制)F3.3FD
      %e指数类型3.14e + 3
      %%百分比类型%
    • (9) getBytes(); //使用平台的默认字符集将此String编码为字节序列,将结果存储到新的字节数组中

      • String s = "abcde";	//对应的ASCII码值为97,98,99,100,101
        byte[] b = s.getBytes();	//数组b = [97,98,99,100,101]
        System.out.println(Arrays.toString(b));	//[97,98,99,100,101]
        
    • getBytes(String charsetName); //使用命名的字符集将此String编码为字节序列,将结果存储到新的字节数组中

      • String s = "123,。";	//对应的UTF-8值为49, 50, 51, 52, 53
        byte[] b = s.getBytes("UTF-8"); //对s字符串进行UTF-8编码,再存于数组b
        System.out.println(Arrays.toSting(b));	//[49, 50, 51, 52, 53]
        
    • getBytes(Charset charset); //使用给定的Charset将此String编码为字节序列,将结果存储到新的字节数组中

      • String s = "123。。"; //对应的Unicode码值为49, 50, 51, -95, -93, -95, -93
        byte[] b = s.getBytes(Charset.forName("Unicode"));	//对s字符串进行Unicode编码,再存于数组b
        System.out.println(Arrays.toString(b));	//[49, 50, 51, -95, -93, -95, -93]
        
    • (10) getChars(int srcBegin,int srcEnd,char[] dst,int dstBegin);

    • //将此字符串中的字符从[srcBegin,srcEnd)区域拷贝至下标从dstBegin开始的目标字符数组中。

    • String s = "helloworld";
      char[] ch = new char[12];
      s.getChars(2,6,ch,2);	//将s字符串中的字符从[2,6)区域拷贝至下标从2开始的字符数组ch中
      System.out.println(Arrays.toString(ch)); //[ ,  , l, l, o, w,  ,  ,  ,  ,  ,  ]
      
    • (11) hashCode(); //返回此字符串的哈希码

      • String s = "ABCDEF";
        int h = s.hashCode();		//获取s字符串的哈希码
        System.out.println(h);		//1923910755
        
    • (12) indexOf(int ch); //返回指定字符第一次出现的此字符串中的索引

    • String s = "helloworld";
      int index = s.indexOf('l');	//第一次出现的l为字符串中的索引为2
      System.out.println(index);	//2
      
    • indexOf(int ch,int fromIndex); //返回指定字符第一次出现的此字符串中的索引,从指定索引处开始搜索

      • String s = "helloworld";
        int index = s.indexOf('o',5);//从s的索引5开始查找,结果为索引6
        System.out.println(index);	//6
        
    • indexOf(String str); //返回指定子字符串第一次出现的字符串中的索引

      • String s = "hello world";
        int index = s.indexOf("world");//第一次出现的"world"的索引为'w'位置
        System.out.println(index);	//6
        
    • indexOf(String str,int fromIndex); //从指定的索引处开始,返回指定子字符串第一次出现的字符串中的索引

      • String s = "How are you?";
        int index = s.indexOf("re",2);//从s的索引2开始查找,找到re,索引为'r'位置
        System.out.println(index);	//5
        
    • (13) intern(); //返回字符串对象的规范表示(将new出来的String转为常量String存于字符串池,并返回其引用)

    • String s1 = new String("12345");
      String s2 = new String("12345");
      System.out.println(s1 == s2);	//false
      s1 = s1.intern();	//将s1的"12345"字符串存于字符串常量池,返回"12345"在常量池中的引用(C中称地址)
      s2 = s2.intern();	//同理,由于此字符串在常量池中已出现,就直接返回已有"12345"在常量池中的引用。
      System.out.println(s1 == s2);	//true
      
    • (14) isBlank(); //若此字符串为空或空格,返回true;否则,返回false

    • isEmpty(); //仅当此字符串为空时,返回true;否则,返回false

      • boolean b1 = "".isBlank();	//b1 = true
        boolean b2 = " ".isBlank();	//b2 = true
        boolean b3 = "A".isBlank();	//b3 = false
        
        boolean b4 = "".isEmpty();	//b4 = true
        boolean b5 = " ".isEmpty();	//b5 = false
        boolean b6 = "A".isEmpty();	//b6 = false
        
    • (15) join(CharSequence delimiter,CharSequence... elements);

    • //返回由CharSequence elements的副本组成的新String,该副本与指定的delimiter的副本连接在一起。

    • CharSequence delimiter = ":";	//元素间的分隔符“:”
      String s = join(delimiter,"当前时间:07","59","30");	//s = "当前时间:07:59:30"
      System.out.println(s);	//当前时间:07:59:30
      
    • join(CharSequence delimiter,Iterable<? extends CharSequence> elements);

      • //返回由String的副本组成的新String ,其中CharSequence elements指定的 delimiter的副本。

      • List<String> el = List.of("当前时间"," 08","30","25");
        String s3 = String.join(":",el); //s = "当前时间: 08:30:25"
        System.out.println(s3);	//当前时间: 08:30:25
        
    • (16) lastIndexOf(int ch); //返回指定字符最后一次出现的索引;无,返回-1。

    • lastIndexOf(int ch,int fromIndex); //返回指定字符在[0,fromIndex]区间内最后一次出现的索引;无,返回-1。

      • String s = "hello world";
        int lastIndex = s.lastIndexOf('l');	//lastIndex = 9
        lastIndex = s.lastIndexOf('o',5);	//lastIndex = 7
        lastIndex = s.lastIndexOf('A');		//lastIndex = -1
        
    • lastIndexOf(String str); //返回指定子字符串最后一次出现的字符串中首字母的索引;无,返回-1。

    • lastIndexOf(String str,int fromIndex); //返回指定字符在[0,fromIndex]区间内最后一次出现的字符串中首字母的索引;无,返回-1。

      • String s = "Java is a language";
        int lastIndex = s.lastIndexOf("is"); //lastIndex = 5
        lastIndex = s.lastIndexOf("a",14);	 //lastIndex = 11
        lastIndex = s.lastIndexOf("is",15);	 //lastIndex = 5
        lastIndex = s.lastIndexOf("is",5);	 //lastIndex = -1(因is不在[0,5]的区域)
        
    • (17) length(); //返回此字符串的长度

    • int length = "1234".length();	//length = 4
      
    • (18) lines(); //返回从此字符串中提取的行的流,由行终止符分隔。

    • //待定~
      
    • (19) matches(String regex); //判断此字符串是否与给定的regex匹配,是,返回true;否,返回false

      • boolean b1 = "123".matches("123");	//b1 = true
        b1 = "hello".matches("he");	//b1 = false
        
    • (20) offsetByCodePoints(int index,int codePointOffset);

      • //返回此字符串的索引,该索引从给定的index向后偏移codePointOffset个位置,若偏移后不存在,抛异常。

      • String s = "helloworld";
        int index = s.offsetByCodePoints(2,7);	//若2+7在s索引域内,index = 9;否则,抛异常
        System.out.println(s.charAt(index));	//打印s索引下标为(2+7)的字符 ——》d
        
    • (21) regionMatches(boolean ignoreCase,int toffset,String other,int ooffset,int len);

    • //测试两个字符串区域是否相等,相等,返回true;否则,返回false。

      • ignoreCase:true,忽略大小写;false,不忽略大小写。
      • toffset:第一个字符串的起始下标。
      • other:第二个字符串。
      • ooffset:第二个字符串的起始下标。
      • len:比较的长度
    • String s1 = "hello world";
      String s2 = "helloWORLD~";
      boolean b = s1.regionMatches(false,0,s2,0,5);	//b = ture
      b = s1.regionMatches(true,6,s2,5,4);			//b = true
      b = s1.regionMatches(false,6,s2,5,3);			//b = false
      
    • regionMatches(int toffset,String other,int ooffset,int len);

      • //测试两字符串区域是否相等,相等,返回true;否则,返回false。

      • String s1 = "hello world";
        String s2 = "helloWORLD~";
        boolean b = s1.regionMatches(0,s2,0,5);	//b = ture
        b = s1.regionMatches(6,s2,5,3);			//b = false
        
    • (22) repeat(int count); //返回一个字符串,其值为此字符串的串联重复count次。

      • String s1 = "123->";
        String s2 = s1.repeat(3);	//s2 = "123->123->123->"
        
    • (23) replace(char oldChar,char newChar); //将此字符串中oldChar字符替换为newChar字符

      • String s = "abc";
        s = s.replace('b','-');	//将s字符串中的字符'b'替换为'-',即s = "a-b"
        
    • replace(CharSequence target,CharSequence replacement);

      • //将此字符串中的target字符序列替换为replacement字符序列

      • String s = "thi is ...";
        CharSequence t = "thi";
        CharSequence r = "This";
        s = s.replace(t,r);	//s = "This is ..."
        
    • replaceAll(String regex,String replacement);

      • //将此字符串中的每一个字符或字符串通过regex匹配替换replacement字符串

        • regex:正则表达式。
        • replacement:替换字符串。
      • String s = "1523sdfw3243df";
        System.out.println(s)	//1523sdfw3243df
        s = s.replaceAll("[1-5]","-"); //将s字符串中任意[1,5]的数替换为"-"(正则表达式的引用)
        System.out.println(s);	//----sdfw----df
        
    • replaceFirst(String regex,String replacement);

      • //将此字符串中的第一个字符或字符串通过regex匹配替换replacement字符串

      • String s = "1523sdfw3243df";
        System.out.println(s)	//1523sdfw3243df
        s = s.replaceFirst("[1-5]","-"); //将s字符串中首个[1,5]的数替换为"-"(正则表达式的引用)
        System.out.println(s);	//-523sdfw3243df
        
    • (24) split(String regex); //将此字符串中每一个字符或字符串通过regex匹配分离,余下的组合成字符数组。

      • String s1 = "2h4e6l3l9o70";
        String[] strings = new String[15];
        strings = s1.split("[0-9]"); //将s1字符串中任意[0,9]的数分离,余下的组合成字符数组
        System.out.println(Arrays.toString(strings)); //[, h, e, l, l, o]
        //将toString()返回的字符串化的数组中全部为"[",", ","]"替换为""(无),组合成新的字符串赋给s2
        String s2 = Arrays.toString(strings).replaceAll("[\\[|, |]|]","");
        System.out.println(s2);	//hello
        
    • split(String regex,int limit); //将此字符串中起始limit-1个字符或字符串通过regex匹配分离,余下的组合成字符数组。

      • String s = "2h4e6l3l9o70";
        String[] strings = new String[15];
        strings = s.split("[0-9]",2); //将s字符串中起始2-1个[0,9]可匹配的数分离,余下的组合成字符数组
        System.out.println(Arrays.toString(strings));//[, h4e6l3l9o70]
        
    • (25) startsWith(String prefix);

      • //测试此字符串是否以指定的前缀开头,是,返回true;否,返回false。
    • startsWith(String prefix,int toffset);

      • //测试从指定索引开始的此字符串是否以指定的前缀开头,是,返回true;否,返回false。

      • String s = "helloworld~";
        boolean b = s.startsWith("he");	//b = true
        b = s.startsWith("llo");	//b = false
        b = s.startsWith("llo",2);	//b = true
        
    • (26) strip(); //返回一个删除此字符串的前导和尾部空格的字符串。

      • (1) 若此字符串为一个或多个空格,返回空字符串。

      • (2) 若此字符串为前缀空格或后缀空格又或者前后空格,删除空格成新字符串返回。

      • (3) 没有空格,直接返回此字符本身。

      • String s1 = "    ",s2 = " hello ",s3 = "abc";
        s1 = s1.strip();	//s1 = ""
        s2 = s2.strip();	//s2 = "hello"
        s3 = s3.strip();	//s3 = "abc"
        
    • stripLeading(); //返回一个删除此字符串前导空格的字符串。

    • stripTrailing(); //返回一个删除此字符串尾部空格的字符串。

      • String s1 = "  abcd  ",s2 = "  abcd  ";
        s1 = s1.stripLeading();	//s1 = "abcd  "
        s2 = s2.stripTrailing();//s2 = "  abcd"
        
    • (27) subSequence(int beginIndex,int endIndex);

      • //截取此字符串索引以[beginIndex,endIndex)部分的字符串,并返回(类型:CharSequence)

      • String s = "abcdefg";
        CharSequence c = s.subSequence(2,6);	//c = "cdef"(截取[2,6))
        s = c.toString();	//s = "cdef"
        
    • subString(int beginIndex);

      • //截取此字符串索引以[beginIndex,尾部]部分的字符串,并返回(类型:String)

      • String s = "123456";
        s = s.subString(2);	//s = "3456"
        
    • subString(int beginIndex,int endIndex);

      • //截取此字符串索引以[beginIndex,endIndex)部分的字符串,并返回(类型:String)

      • String s = "abcdefg";
        s c = s.subSequence(2,6);	//s = "cdef"(截取[2,6))
        
    • (28) toCharArray(); //将此字符串转换为新的字符数组。

      • String s = "hello";
        byte[] b = s.toCharArray();	//数组b = {h,e,l,l,o};
        System.out.println(Arrays.toString(b));	//[h, e, l, l, o]
        
    • (29) toLowerCase(); //默认语言环境下,将此字符串中所有大写字母转为小写。

      • String s = "ABC。";
        s = s.toLowerCase();	//s = "abc。"
        
    • toLowerCase(Locale locale);

      • //根据给定Locale规则,将此字符串中所有大写字母转为小写。

      • String s1 = "HELLO WORLD~",s2 = "ABCD~";
        s1 = s1.toLowerCase(Locale.GERMAN);	//s = "hello world~"
        s2 = s2.toLowerCase(Locale.ITALIAN);//s = "abcd~"
        
    • toUpperCase(); //默认语言环境下,将此字符串中所有小写字母转为大写。

      • String s = "abcd~";
        s = s.toUpperCase();	//s = "ABCD~"
        
    • toUpperCase(Locale locale);

      • //根据给定Locale规则,将此字符串中所有小写字母转为大写。

      • String s1 = "hello world~",s2 = "abcd~";
        s1 = s1.toUpperCase(Locale.GERMAN);	//s = "HELLO WORLD~"
        s2 = s2.toUpperCase(Locale.ITALIAN);//s = "ABCD~"
        
    • (30) toStirng(); //返回对象值(此字符串)。

      • System.out.println("abc".toString());	//abc
        
    • (31) trim(); //返回一个字符串,其值为此字符串删除了所有前导和尾部空格(其值≤'U+0020'(空格字符)的任意字符)。

      • String s1 = " \u0000\u0020hello world \u0010\u0020";
        String s2 = "\u0021\u0020 hello world \u0064";
        s1 = s1.trim();	//s1 = "hello world"
        s2 = s2.trim(); //s2 = "!  hello world d"
        
        注意:Java中的转义字符。
        /**
         *	\xxx			 :八进制转义字符 
         *	\uxxxx(或\Uxxxx):十六进制转义字符
         */
        
    • (32) valueOf(boolean b); //返回boolean参数的字符串表示形式。

      • boolean b = false;
        String s = String.valueOf(b);		//s = "false"
        
    • valueOf(char c); //返回char参数的字符串表示形式。

      • char c = '\u0064';	//c = 'd';
        String s = String.valueOf(c);		//s = "d"
        
    • valueOf(char[] data); //返回char数组的字符串表示形式。

      • char[] ch = {'h','e','l','l','o'};
        String s = ch.valueOf(ch);			//s = "hello"
        
    • valueOf(char[] data,int offset,int count);

      • //将char数组data从offset下标开始统计count个字符,并字符串化返回。

      • char[] c = {'0','1','2','3','4','5','6','7','8','9'};
        String s = String.valueOf(c,3,5);	//s = "34567"
        
    • valueOf(double d); //返回double参数的字符串表示形式。

      • double d = 3.1415926;
        String s = String.valueOf(d);		//s = "3.1415926"
        
    • valueOf(float f); //返回float参数的字符串表示形式。

      • float f = 1.414F;
        String s = String.valueOf(f);		//s = "1.414"
        
    • valueOf(int i ); //返回int参数的字符串表示形式。

      • int i = 65535;
        String s = String.valueOf(i);		//s = "65535"
        
    • valueOf(long l); //返回long参数的字符串表示形式。

      • long l = 123456789L;
        String s = String.valueOf(l);		//s = "123456789"
        
    • valueOf(Object obj); //返回Object参数的字符串表示形式。

      • Object o = 12345;
        String s = String.valueOf(o);		//s = "12345"
        

      建议:在使用时,多看看Java API文档中的String类中的常用方法具体分析。

3.3 StringBuffer与StringBuilder(重点!)

String类加法拼接字符串的缺陷,分析:

在这里插入图片描述

注意通过加法拼接的字符串能避免尽量避免(因加多了比较耗内存,且在程序运行期间无法释放)

若要拼接字符串,应使用StringBuffer、StringBuilder。

  • (1) 与String不同的是StringBuffer、StringBuilder支持可变字符序列(意味着该类型的字符串值可修改)。

  • (2) 重点在于解决了字符串拼接的问题(避免加法拼接产生不必要的内存垃圾)。

    • 原因:其内部实现了字符串在内存中没有缓存,每次拼接后都会被及时的回收。
      
/**
 * 用法(举其一):
 * 1、先new一个无参的StringBuffer();
 * 2、再用append()方法拼接字符串。
 * 3、若将其当成String类的字符串使用,可借助toString()方法转成String类字符串。
 */
public class Main {
    public static void main(String[] args) {
        StringBuffer str = new StringBuffer();
        str.append("咬定青山不放松,");
        str.append("立根原在破岩中。\n");
        str.append("千磨万击还坚劲,");
        str.append("任尔东西南北风。");
        String text = str.toString();
        System.out.println(text);
    }
}
//此用法虽没有“+”拼接方便,但节省了内存(推荐)在有限的范围内拼的越多越能体现其优越性。StringBuilder用法同理。

效率与安全:
    StringBuilder :效率高,线程不安全的实现;
    StringBuffer  :效率相对低,线程安全的实现。
1、常用构造方法
    • StringBuffer(); //构造一个字符串缓存区,初始容量为16个字符(不够,将自动扩容)。
    • StringBuffer(String str); //构造一个初始化为指定字符串内容的字符串缓冲区(同理)。
2、常用方法
    • append(String str); //将指定的字符串追加到此字符序列。
    • toString(); //将此字符序列转成String类字符串。

    StringBuilder的常用方法和常用方法与StringBuffer一致。

其他具体参考:Java API手册。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值