基本数据类型的包装类提供了一些常用的方法来进行数据转换、比较大小等操作,或用于表示和处理特定的数据范围、最大值、最小值等。例如,可以使用Integer.parseInt()将字符串转换为整数,或使用Double.compare()比较两个浮点数的大小;Integer.MAX_VALUE表示整数的最大值,Character.isDigit()用于判断字符是否为数字。
允许在集合框架中使用:集合框架(如List、Set、Map等)只能存储对象,而不能存储基本数据类型。通过使用基本数据类型的包装类,可以自动将基本数据类型转换为对象,从而使其能够被添加到集合中。
支持泛型类型:Java中的泛型不支持基本数据类型,只支持引用数据类型。通过使用基本数据类型的包装类,可以实现基本数据类型的泛型支持。
需要注意的是,基本数据类型的包装类是不可变的(immutable),也就是说它们的值一旦初始化就不能修改。每次对基本数据类型进行操作时,都会创建一个新的包装类对象。
不直接存储数据值本身,而是存储对数据对象的引用(内存地址)的类型。
Java中的引用数据类型包括类(Class)、接口(Interface)、数组(Array)等。
通过使用引用数据类型,我们可以创建复杂的数据结构,如对象、数组和集合等。
引用数据类型具有以下特点:
注意:当有小数参与运算,结果可能不精确。
数字相加:
当数据类型不同时需要进行转换:隐式转换(范围小转范围大)和强制转换(范围大转范围小)
字符串相加:
直接写一起
字符相加:
变成ASCLL码再相加
第一种格式:
if (关系表达式){
语句体; //即关系表达式为true才执行语句体
}
第二种格式:
if (关系表达式){
语句体1;
}else{
语句体2;
}
第三种格式:
if (关系表达式){
语句体1;
}else if{
语句体2; //从上往下依次判断,一个为真就执行并结束
}
…
else{
语句体n+1;
}
switch (表达式){ //这里表达式会得到一个值
case 值1: //得到的值和case后面的值依次对比看执行哪个
语句体1;
break; //遇到break时跳出循环
case 值2:
语句体2;
break;
…
default: //上面都不能执行时则执行default
语句体n+1;
break;
}
扩展方法一:
switch (number){
case 1 -> System.out.println("一");
case 2 -> System.out.println("二");
case 3 -> System.out.println("三");
default -> System.out.println("没有该选项");
}
扩展方法二:
switch (week){
case 1,2,3,4,5 -> System.out.println("工作日");
case 6,7 -> System.out.println("休息日");
default -> System.out.println("录入不合法");
}
for(初始条件;循环停止条件;自增){
循环体;
}
for循环扩展知识:
求和变量不能定义在循环内,这样该变量只在循环所属的大括号内有用。在循环内的求和变量,也只在当前的循环中是有用的。i=1时定义的sum变量,在本次循环结束后就被内存清掉了;下一次i=2循环时会再定义一次。
初始化语句;
While(条件控制语句){
循环体语句;
条件控制语句;
}
初始化语句;
do{
循环体语句;
条件控制语句;
}while(条件判断语句)
数组:作用类似于变量,可以存储同种数据类型的多个值。
静态初始化(指定值):
动态初始化(指定长度):
数据类型[] 数组名= new 数据类型[数组长度];
常见操作:求最值、求平均、打乱等。
通过写类来表示属性和方法,再通过对象具体实现属性和方法。
由于Java中不允许多继承,因此又产生了接口来补充。
面向对象的三大特点:
多态的前提:
有继承关系;
有父类引用指向子类对象;
有方法重写。
static:
final:
Q:为什么要抽象?
A:抽象类和抽象方法在Java中的出现主要是为了支持面向对象编程中的抽象概念和多态性。通过将抽象类作为父类,可以实现对不同子类的统一处理。而抽象方法的存在要求子类必须实现具体的方法体,从而实现不同子类之间的多态性。
抽象方法和抽象类的本质之一是为了在一个大项目中提供统一的处理方式和规范。通过定义抽象方法,强制子类对这些方法进行重写,确保在不同的子类中具有相同的方法签名和行为,从而实现统一的处理逻辑。
抽象类是一种特殊的类,用于表示不能被实例化的类。它通常用作其他类的基类(父类),提供一组抽象方法和非抽象方法的定义。其中,抽象方法是一种没有实现代码的方法声明,只有方法签名,没有方法体。
抽象类的子类有两种选择:
要么继续声明为抽象类;
要么重写父类的所有抽象方法。
Math类所在包为java.lang包,因此无需导包。
Math类被final修饰了,因此不能被继承。
Math类包含执行基本数字运算的方法,我们可以使用Math类完成基本的数学运算。
没有构造方法,不能直接通过new关键字去创建Math类的对象。
Math类中的方法都是静态的,因此在使用的时候我们可以直接通过类名去调用。即Math.方法名
。
public static int abs(int a)
// 返回参数的绝对值
public static double ceil(double a)
// 返回大于或等于参数的最小整数
public static double floor(double a)
// 返回小于或等于参数的最大整数
public static int round(float a)
// 按照四舍五入返回最接近参数的int类型的值
public static int max(int a,int b)
// 获取两个int值中的较大值
public static int min(int a,int b)
// 获取两个int值中的较小值
public static double pow (double a,double b)
// 计算a的b次幂的值
public static double random()
// 返回一个[0.0,1.0)的随机值
System包含了系统操作的一些常用的方法,比如获取当前时间所对应的毫秒值,再比如终止当前JVM等等。
System.方法名
public static long currentTimeMillis()
// 获取当前时间所对应的毫秒值
//(当前时间为0时区所对应的时间即就是英国格林尼治天文台旧址所在位置)
public static void exit(int status)
// 终止当前正在运行的Java虚拟机,0表示正常退出,非零表示异常退出
public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);
// 进行数值元素copy
Runtime表示Java中运行时对象,可以获取到程序运行时设计到的一些信息。
public static Runtime getRuntime() //当前系统的运行环境对象
public void exit(int status) //停止虚拟机
public int availableProcessors() //获得CPU的线程数
public long maxMemory() //JVM能从系统中获取总内存大小(单位byte)
public long totalMemory() //JVM已经从系统中获取总内存大小(单位byte)
public long freeMemory() //JVM剩余内存大小(单位byte)
public Process exec(String command) //运行cmd命令
Object类所在包是java.lang包,Object 是类层次结构的根,每个类都可以将 Object 作为超类。
所有类都直接或者间接的继承自该类;换句话说,该类所具备的方法,其他所有类都继承了。
一般很少创建Object类的对象,而是创建其子类的对象。
public String toString()
//返回该对象的字符串表示形式(可以看做是对象的内存地址值)
public boolean equals(Object obj)
//比较两个对象地址值是否相等;true表示相同,false表示不相同
protected Object clone()
//对象克隆
深克隆:基本数据类型拷贝过来,字符串复用,引用数据类型会重新创建新的;
浅克隆:不管对象内部的属性是基本数据类型还是引用数据类型,都完全拷贝过来; 基本数据类型拷贝过来的是具体的数据,引用数据类型拷贝过来的是地址值。Object类默认的是浅克隆
Objects类提供了一些对象常见操作的方法。比如判断对象是否相等,判断对象是否为null等等。
public static String toString(Object o)
// 获取对象的字符串表现形式
public static boolean equals(Object a, Object b)
// 比较两个对象是否相等
public static boolean isNull(Object obj)
// 判断对象是否为null
public static boolean nonNull(Object obj)
// 判断对象是否不为null
存储整数的时候,Java中默认是int类型。
int类型有取值范围:-2147483648 ~ 2147483647。
如果数字过大,我们可以使用long类型,但是如果long类型也表示不下怎么办呢?
就需要用到BigInteger,可以理解为:大的整数。
BigInteger所在包是在java.math包下,因此在使用的时候就需要进行导包。
public BigInteger(int num, Random rnd)
//获取随机大整数,范围:[0 ~ 2的num次方-1]
public BigInteger(String val)
//获取指定的大整数
public BigInteger(String val, int radix)
//获取指定进制的大整数
下面这个不是构造,而是一个静态方法获取BigInteger对象
public static BigInteger valueOf(long val)
//静态方法获取BigInteger的对象,内部有优化
成员方法:
public BigInteger add(BigInteger val) //加法
public BigInteger subtract(BigInteger val) //减法
public BigInteger multiply(BigInteger val) //乘法
public BigInteger divide(BigInteger val) //除法
public BigInteger[] divideAndRemainder(BigInteger val) //除法,获取商和余数
public boolean equals(Object x) //比较是否相同
public BigInteger pow(int exponent) //次幂、次方
public BigInteger max/min(BigInteger val) //返回较大值/较小值
public int intValue(BigInteger val) //转为int类型整数,超出范围数据有误
在使用float或者double类型的数据在进行数学运算的时候,很有可能会产生精度丢失问题。计算机底层在进行运算的时候,使用的都是二进制数据; 当我们在程序中写了一个十进制数据 ,在进行运算的时候,计算机会将这个十进制数据转换成二进制数据,然后再进行运算,计算完毕以后计算机会把运算的结果再转换成十进制数据给我们展示。
如果我们使用的是整数类型的数据进行计算,那么在把十进制数据转换成二进制数据的时候不会存在精度问题; 如果我们的数据是一个浮点类型的数据,有的时候计算机并不会将这个数据完全转换成一个二进制数据,而是将这个将其转换成一个无限的趋近于这个十进数的二进制数据; 这样使用一个不太准确的数据进行运算的时候, 最终就会造成精度丢失;为了提高精度,Java就给我们提供了BigDecimal供我们进行数据运算。
构造方法:
// 构造方法获取BigDecimal对象
public BigDecimal( double val)
public BigDecimal (String val)
// 静态方法获取BigDecimal对象
public static BigDecimal valueof(double val)
成员方法:
public BigDecimal add(BigDecimal value) // 加法运算
public BigDecimal subtract(BigDecimal value) // 减法运算
public BigDecimal multiply(BigDecimal value) // 乘法运算
public BigDecimal divide(BigDecimal value) // 触发运算
String str = "Hello"
; 右边直接用双引号String()
:构造一个空。String(byte[] bytes)
:用 byte 数组来构造字符串。String(char[] value)
:用 char 数组来构造字符串。String(String original)
:用已存在的字符串来构造新的字符串。String(StringBuffer buffer)
:用字符串缓冲区中的内容来构造新的字符串。String(StringBuilder builder)
:用字符串生成器中的内容来构造新的字符串。public int length()
:获取字符串当中含有的字符个数,拿到字符串长度。
public String concat(String str)
:将当前字符串和参数字符串拼接成为返回值新的字符串。
public char charAt(int index)
:获取指定索引位置的单个字符。(索引从0开始。)
public int indexOf(String str)
:查找参数字符串在本字符串当中首次出现的索引位置,如果没有返回-1值。
字符串的截取方法用 substring 函数。
public String substring(int index)
:截取从参数位置一直到字符串末尾,返回新字符串。
public String substring(int begin, int end)
:截取从begin开始,一直到end结束,中间的字符串。[begin,end),包含左边,不包含右边。
public char[] toCharArray()
:将当前字符串拆分成为字符数组作为返回值。
public byte[] getBytes()
:获得当前字符串底层的字节数组。
public String replace(CharSequence oldString, CharSequence newString)
:将所有出现的老字符串替换成为新的字符串,返回替换之后的结果新字符串。
public String[] split(String regex)
:按照参数的规则,将字符串切分成为若干部分。
1、toString()
toString() 方法:返回字符串本身,返回值为 String 类型
2、length()
length() 方法:返回字符串字符序列的长度(空格也算),返回值为 int 类型
String str = new String("Hello World");
System.out.println(str.length());//11
3、getBytes()
getBytes() 方法:将当前字符串内容转换为 byte 数组并返回,返回值为 byte[],该方法的返回值可作为 String构造方法的参数
//将String类型转换为byte数组类型并打印
//先将字符串拆分为字符,再将每个字符转换为byte类型,也就是获取所有字符的ASCII码
String str = new String("Hello World");
byte[] bytes = str.getBytes();
for (int i = 0; i < bytes.length; i++) {
System.out.println("下标为" + i + "的元素为:" + bytes[i]);//打印的是每个字母对应的ASCII码
}
4、toCharArray()
toCharArray() 方法:将当前字符串内容转换为 char 数组并返回,返回值为 char[],该方法的返回值可作为 String构造方法的参数
String str = new String("Hello World");
char[] cArr = str.toCharArray();
for (int i = 0; i < str.length(); i++) {
System.out.println("下标为" + i + "的元素为:" + cArr[i]);//打印的是每个字母
}
5、charAt(int index)
charAt(int index) 方法:用于返回字符串指定位置的字符,返回值为 char 类型,参数为 int 类型
String str = new String("Hello World");
for (int i = 0; i < str.length(); i++) {
System.out.println("下标为" + i + "的元素为:" + str.charAt(i));//打印的是每个字母
}
6、isEmpty()
isEmpty() 方法:判断字符串是否为空,返回值为 boolean 类型,查看该方法的源码可知字符串的 length 为0则为空.
注意:开发中判断字符串是否为空一般采用 org.apache.commons.lang3 下的 StringUtils 中的静态方法 isEmpty() 和 isBlank();
StringUtils 类与 String 类的区别在于:StringUtils 类是 null 安全的,即如果输入参数 String 为null,则不会抛出 NullPointerException 空指针异常,代码考虑更全面
String str1 = null;
String str2 = "";
String str3 = " ";
System.out.println(str2.isEmpty());//true
System.out.println(str3.isEmpty());//false
System.out.println(str1.isEmpty());//java.lang.NullPointerException
//拓展StringUtils.isBlank()和StringUtils.isEmpty()
StringUtils.isBlank(null) = true
StringUtils.isBlank("") = true
StringUtils.isBlank(" ") = true
StringUtils.isEmpty(null) = true
StringUtils.isEmpty("") = true
StringUtils.isEmpty(" ") = false
7、equals(Object anObject)
equals(Object anObject) 方法:比较字符串内容是否相等并返回,返回值为 boolean 类型
equalsIgnoreCase(String anotherString)方法:比较字符串内容是否相等并返回,返回值为 boolean类型,不考虑大小写, 如:'A’和’a’是相等
String str = new String("Hello World");
//注意:开发中作比较一般常量值在前,变量值在后
System.out.println("hello world".equals(str));//false
System.out.println("hello world".equalsIgnoreCase(str));//true
8、compareTo(String anotherString)
compareTo(String anotherString) //比较调用对象和参数对象的大小关系,返回值为 int
compareToIgnoreCase(String str) //比较调用对象和参数对象的大小关系,返回值为 int类型,不考虑大小写,也就是’a’和’A’是相等的关系
比较大小的方法:例如 A.compareTo(B),拿方法调用者(A)的字符依次与方法参数(B)的字符作比较,即用 A 的 ASCII码减去B 的ASCII码;结果有三种:负整数、正整数、零。负整数即按字典顺序 A 在 B 之前,正整数即 A 在 B 之后,零则为字符串相等。
注意:比较出大小就不往后进行,即从第一个字符串开始比较,相同则比较下一个,直到比较出大小或比较到最后一个字符。
String str = "hello";
System.out.println(str.compareTo("world"));
// 'h' - 'w' => 104 - 119 => -15
System.out.println(str.compareTo("haha"));
// 'e' - 'a' => 101 - 97 => 4
System.out.println(str.compareTo("heihei"));
// 'l' - 'i' => 108 - 105 => 3
System.out.println(str.compareTo("helloworld"));
// 长度: 5 - 10 => -5
System.out.println(str.compareToIgnoreCase("HELLO"));
// 0
9、contains(CharSequence s)
contains(CharSequence s) 方法:判断当前字符串是否包含参数指定的内容,返回值为 boolean类型,参数CharSequence 为一个接口,CharSequence 是 char值的可读序列,参数可以为String、StringBuilder、StringBuffer等类型
String str = "Give you some color to see see";
System.out.println(str.contains("some"));//true
System.out.println(str.contains("Some"));//false
10、trim()
trim() 方法:返回去掉前导和尾随空白的字符串,返回值为 String 类型
String str = " Hello World ";
System.out.println(str.trim());//Hello World
System.out.println(str.length());//13
System.out.println(str.trim().length());//11
11、toUpperCase() 和 toLowerCase()
toUpperCase() 方法:返回字符串的大写形式,返回值为 String 类型 toLowerCase()方法:返回字符串的小写形式,返回值为 String 类型
此两种方法经常用于在对字符串做判断时使用,因为要判断的字符串可能为驼峰式或者不规则的方式,故先将判断的字符串转为大写或者小写,然后与常量去做比较。
String str = "Hello World";
System.out.println(str.toLowerCase());//hello world
System.out.println(str.toUpperCase());//HELLO WORLD
12、substring(…)
该方法有两个重载的方法,分别为: substring(int beginIndex, int endIndex) 方法:返回字符串中从下标
beginIndex(包括) 开始到 endIndex(不包括) 结束的子字符串,返回值为 String 类型,参数为 int 类型substring(int beginIndex) 方法:返回字符串中从下标 beginIndex(包括)
开始到字符串结尾的子字符串,返回值为 String 类型,参数为 int 类型注意:Java 中涉及到区间的问题,一般都为 左边包括,右边不包括,即左开右闭,“[ x , y )”
13、replace(…)
replace(char oldChar, char newChar)方法:使用参数newChar替换此字符串中出现的所有参数oldChar,返回值为 String 类型,参数为 char 类型
replace(CharSequence target, CharSequence replacement)方法:用新字符串replacement替换所有的旧字符串target,返回值为 String 类型,参数为 CharSequence 接口
System.out.println("Hello World".replace('o', 'e'));//Helle Werld
System.out.println("JonL".replace('q', 'x'));//JonL 无改变则返回原字符串
System.out.println("aaa".replace("aa", "b"));//ba
14、split(String regex)
split(String regex)方法:参数regex为正则表达式,以regex所表示的字符串为分隔符,将字符串拆分成字符串数组,结尾的空字符串不包含在结果数组中,返回值为String[] 类型,参数为 String 类型
String str = "boo:and:foo";
String[] split = str.split(":");//结果为:"boo", "and", "foo"
String[] split = str.split("o");//结果为:"b", "", ":and:f"
15、startsWith(…) 和 endsWith(…)
startsWith(String prefix) 方法:判断字符串是否以参数字符串开头,返回值为 boolean 类型,参数为String 类型
startsWith(String prefix, int toffset) 方法:从指定位置开始是否以参数字符串开头,返回值为 boolean 类型,参数 prefix 为 String 类型,toffset 为 int 类型
endsWith(String suffix) 方法:判断字符串是否以参数字符串结尾,返回值为 boolean 类型,参 数为 String类型
String str = "Give you some color to see see";
System.out.println(str.startsWith("G"));//true
System.out.println(str.startsWith(" "));//false
System.out.println(str.startsWith("you", 5));//true
System.out.println(str.endsWith(" "));//false
System.out.println(str.endsWith("see"));//true
16、indexOf(…) 和 lastIndexOf(…)
方法声明 | 功能介绍 |
---|---|
int indexOf(int ch) | 用于返回当前字符串中参数 ch 指定的字符第一次出现的下标 |
int indexOf(int ch) | 用于返回当前字符串中参数 ch 指定的字符第一次出现的下标 |
int indexOf(int ch, int fromIndex) | 用于从 fromIndex(包含) 位置开始查找ch指定的字符 |
int indexOf(String str) | 在字符串中检索 str 返回其第一次出现的位置,若找不到返回-1 |
int indexOf(String str, int fromIndex) | 表示从字符串的 fromIndex(包含) 位置开始检索str第一次出现的位置 |
int lastIndexOf(int ch) | 用于返回参数 ch 指定的字符最后一次出现的下标 |
int lastIndexOf(int ch, int fromIndex) | 用于从 fromIndex(包含) 位置开始反向查找 ch 指定字符出现的下标,若找不到返回-1 |
int lastIndexOf(String str) | 返回 str 指定字符串最后一次出现的下标 |
int lastIndexOf(String str, int fromIndex) | 用于从 fromIndex(包含) 位置开始反向搜索的第一次出现的下标 |
String str = "Good Good Study, Day Day Up!";
System.out.println(str.indexOf('g')); // -1 代表查找失败
System.out.println(str.indexOf('G')); // 0 该字符第一次出现的索引位置
System.out.println(str.indexOf('G', 0)); // 0
System.out.println(str.indexOf('G', 1)); // 5
// 查找字符串
System.out.println(str.indexOf("day")); // -1
System.out.println(str.indexOf("Day")); // 17 字符串中第一个字符的下标
System.out.println(str.indexOf("Day", 17)); // 17 字符串中第一个字符的下标
System.out.println(str.indexOf("Day", 18)); // 21 字符串中第一个字符的下标
// 字符串内容的反向查找
System.out.println(str.lastIndexOf("Day")); // 21
System.out.println(str.lastIndexOf("Day", 21)); // 21
System.out.println(str.lastIndexOf("Day", 20)); // 17
System.out.println(str.lastIndexOf("Day", 15)); // -1
String对象是不可改变的。每次使用 System.String类中的方法之一时,都要在内存中创建一个新的字符串对象,这就需要为该新对象分配新的空间。在需要对字符串执行重复修改的情况下,与创建新的 String对象相关的系统开销可能会非常昂贵。
如果要修改字符串而不创建新的对象,则可以使用System.Text.StringBuilder类。例如,当在一个循环中将许多字符串连接在一起时,使用 StringBuilder类可以提升性能。
StringBuilder MyStringBuilder = new StringBuilder(“Hello World!”);
StringBuilder s = new StringBuilder("0123456789");
s.delete(0,3);//从0位置开始,到3结束(左闭右开,不包括3)
替换replace(int i,int j,String str)
StringBuilder s = new StringBuilder("0123456789");
s.replace(3, 5, "aaaaa");
插入insert(int i,String str)
StringBuilder s = new StringBuilder("0123456789");
s.insert(5, "aaaaa");
获取字符 charAt(int i)
StringBuilder s = new StringBuilder("0123456789");
System.out.println(s.charAt(3));
Q:该类出现的原因?
A:开发中可能会遇到字符串列表根据分隔符进行拼接的需求。原有的stringbuilder太死板,不支持分割,如果想让最终的字符串以逗号隔开,需要这样写:
IntStream.range(1,10).forEach(i->{
sb.append(i+"");
if( i < 10){
sb.append(",")
}
但使用StringJoiner后则可以写为:
StringJoiner sj = new StringJoiner(",");
IntStream.range(1,10).forEach(i->sj.add(i+""));