文章目录
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。
- date1.compareTo(data2);
-
public boolean equals(Object obj);//比较两个日期是否相等
- date1.equals(date2);
- 若date1 == date2,return true;
- 若date1 != date2,return false;
- date1.equals(date2);
-
-
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手册。