API
API概述
-
什么是API
API (Application Programming Interface) :应用程序编程接口
-
java中的API
指的就是 JDK 中提供的各种功能的 Java类,这些类将底层的实现封装了起来,我们不需要关心这些类是如何实现的,只需要学习这些类如何使用即可,我们可以通过帮助文档来学习这些API如何使用。
如何使用API帮助文档
包装类(封装类)
1.5版本之后 自动拆装包
byte---Byte short---Short int---Integer long---Long
float---Float double---Double char---Character boolean---Boolean
1.八个包装类都在同一个包下 java.lang包 不需要import导包直接使用
2.八个包装类中有六个是与数字相关 都默认继承父类Number
3.八个包装类都实现了Serializable, Comparable
4.八个包装类都有带自己对应类型参数的构造方法
八个包装类中有七个(除了Character)还有构造方法重载 带String类型
5.创建对象 对象调用方法
拆包
有六个与数字相关的类都继承Number xxxValue(); 将一个包装类类型转化为对应的基本类型(拆包)
Integer i1 = new Integer(10);//引用数据类型 包装类
int value = i1.intValue();//基本数据类型 10
Integer i2 = 10;
int value = new Integer(10);
int value = Integer.parseInt("123"); Float.parseFloat("123.45")
int value = new Integer("123");
6.经常在笔试中出现的问题
Integer i1 = 10;
Integer i2 = 10;
Integer i3 = new Integer(10);
Integer i4 = new Integer(10);
System.out.println(i1==i2);// true--->如果数字范围超过(-128,127] false
System.out.println(i1==i3);// false
System.out.println(i3==i4);// false
System.out.println(i1.equals(i2));//true
System.out.println(i1.equals(i3));//true
System.out.println(i3.equals(i4));//true
==与equals()区别
==可以比较基本数据类型 也可以比较引用数据类型 (变量中存储的内容)
如果比较基本类型比较是变量中存储的值
如果比较引用类型比较是变量中存储的地址引用
equals()是Object类中继承过来的方法 每一个引用类型都可以调用
默认继承的equals()方法比较与==一致 如果想要改变比较规则 可以重写equals方法
由于Integer类就重写了equals() 所以Integer比较的是数值
2.考察Integer类加载的时候 自己有一个静态的空间
空间内立即加载 Integer类型的数组 内存储256个Integer对象 -128 ~ 127
如果我们用的对象范围在这之内Integer i1 = 10; 直接取静态区中找对应的对象
如果我们用的对象范围超出了范围(-128~127)Integer i1 = 1000; 会帮我们在堆区创建一个新的Integer对象
数学相关
与数学相关的类
Math类
- 所属的包java.lang
- Math构造方法是私有的 我们不能直接调用创建对象
- 由于Math中提供的属性及方
- 法都是static 不需要创建对象
Math常用的方法
- abs()返回给定数字的绝对值 (参数 int long float double)
- double = ceil()向上取整
- double = floor()向下取整
- double = rint()临近的整数 如果两边距离一样 则返回偶数
- double = round() 四舍五入的整数
- max(a,b) min(a,b) (参数int long float double)
- pow(a,b) a的b次方 (参数double 返回值double)
- sqrt(double a) 获取给定参数的平方根
- double = random(); 随机产生一个 [0.0--1.0)
Math生成小数缺陷
5.Math.random()计算小数的时候精确程度可能有些损失
0-9之间的随机整数
int value = (int)(Math.random()*10);
需求:生成5.0---10.9之间的小数
(Math.random()*6)+5
0.0---0.99999 * 6
(0.0---5.49999)+5
Random类
- 在java.util包中的类 需要import导入
- 没有任何继承关系 默认继承Object类
查找构造方法--->如何创建对象?
Random r = new Random();
Random类的常用方法
- r.nextInt(); 随机产生 int取值范围的整数 有正有负
- r.nextInt(int bound); 随机产生一个 [0--bound) 整数
注意bound必须为正数 否则会出现如下的运行时异常
IllegalArgumentException
- r.nextFloat() 随机产生一个 [0.0---1.0)
- r.nextBoolean() 随机产生一个boolean值 true false
小数随机数
r.nextInt(6)+5+r.nextFloat();//5.0~10.9范围
r.nextInt(6)+5 生成的是[5,10]
r.nextFloat() 生成的是[0.0,1.0)
UUID类
- 所属的包 java.util 需要import导入
- 没有任何继承关系 默认继承Object类
- 构造方法有 没有无参数的 我们通常不会创建对象
- UUID uuid = UUID.randomUUID();
- System.out.println(uuid.toString());//数据库表格主键 primary key
- 产生一个32位的随机元素 每一个位置是一个16进制的数字
BigInteger类
大整数 long -2的63次方 ~ 2的63次方-1
1.所属的包java.math 需要import导入
2.继承自Number
3.如何创建对象 提供的构造方法全部都是带参数的
通常利用带String参数的构造方法创建这个类的对象
BigInteger bi = new BigInteger("123");
BigInteger类中的常用方法
做四则运算
加add() 减subtract() 乘multiply() 除divide()
BigInteger b1 = new BigInteger("123");
BigInteger b2 = new BigInteger("456");
System.out.println(b1.add(b2));//579
5.小例子 设计一个方法 用来计算给定数字的阶乘 5 12345==120
//设计一个方法 用来计算给定数字的阶乘
//参数 返回值
public class MathToMethods{
public BigInteger factorial(int num){
BigInteger result = new BigInteger("1");
for(int i=1;i<=num;i++){
result = result.multiply(new BigInteger(i+""));
}
return result;
}
}
public class TestMathDemo {
public static void main(String[] args) {
MathToMethods mathToMethods=new MathToMethods();
Scanner num=new Scanner(System.in);
System.out.println("请你输入一个数字,我帮你计算它的阶乘");
int number=num.nextInt();
BigInteger result =mathToMethods.factorial(number);
System.out.println("它的阶乘是"+result);
}
}
BigDecimal类
超过了double取值范围
1.所属的包 java.math包
2.继承Number类
3.通常也是可以通过 带String参数 构建对象
4.类中的常用方法
做四则运算
add() subtract() multiply() divide()
两个参数前面是保留小数点之后的位数 后面参数是设置的模式
对象.setScale(2,BigDecimal.ROUND_DOWN);
BigDecimal中定义的 static int ROUNF_DOWN等属性
小数点后保留两位数字并且是向下取整的方式
BigDecimal decimal = new BigDecimal("123.456789");
//小数点之后保留两位 按照向下取整的方式进行截取
decimal = decimal.setScale(2,BigDecimal.ROUND_DOWN);
System.out.println(decimal);//123.4
BigDecimal.ROUND_DOWN
,向下取整,不在后面补0
BigDecimal.ROUND_UP
,向上取整,不在后面补0
DecimalFormat类
1.所属的包 java.text
2.import导入才能使用
3.通过带String参数的构造方法创建一个格式化对象
0(必须存在)
(可有可无)
4.调用format方法将一个小数格式化成一个字符串
DecimalFormat df = new DecimalFormat("000.###");
System.out.println(df.format(12.45));//12.45
System.out.println(df.format(12.455));//12.55
System.out.println(df.format(12.45678));//12.457
超过#个数的都四舍五入
Scanner类
- 所属的包java.util包 需要import导包
- 通过一个带输入流的构造方法创建对象
常用方法
nextInt() nextFloat() next() nextLine()
Arrays类
- 所属的包java.util包 需要import导包
import java.utli.Arrays;
toString
返回数组的字符串形式
String = Array.toString(arr)
public class Test {
public static void main(String[] args) {
int[] arr = new int[]{1, 2, 3};
System.out.println(arr);//[I@119d7047
System.out.println(Arrays.toString(arr));//[1, 2, 3]
}
}
底层就是利用StringBuilder进行拼接
sort
sort(自然排序和定制排序) Integer arr[] = {1,-1,7,0,89};
binarySearch通过二分搜索法进行查找 , 要求必须排好序
int index = Array.binarySearch(arr , 3);
public class Test {
public static void main(String[] args) {
Integer[] arr = new Integer[]{3, 1, 2};
System.out.println(Arrays.toString(arr));//[3, 1, 2]
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));//[1, 2, 3]
}
}
- 因为数组是引用类型,所有通过sort排序后,会直接影响到 实参arr
- sort方法默认为从小到大排序
- 还可以调用sort的重载方法,排序规则自己定
从小到大排序
public class Test {
public static void main(String[] args) {
Integer[] arr = new Integer[]{3, 1, 2};
System.out.println(Arrays.toString(arr));//[3, 1, 2]
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i1 - i2;//从小到大排序
}
});
System.out.println(Arrays.toString(arr));//[1, 2, 3]
}
}
从大到小排序
public class Test {
public static void main(String[] args) {
Integer[] arr = new Integer[]{3, 1, 2};
System.out.println(Arrays.toString(arr));//[3, 1, 2]
Arrays.sort(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer i1 = (Integer) o1;
Integer i2 = (Integer) o2;
return i2 - i1;//从大到小排序
}
});
System.out.println(Arrays.toString(arr));//[3, 2, 1]
}
}
binarySearch
- int index = binarySearch(arr , 3);
- 先排好顺序,只能是从小到大的顺序
- 然后调用方法传入一个数组,传入值,会返回对应值的索引
- 如果对应值不存在,会return -(low + 1) low是他应该出现的位置索引
public class Test {
public static void main(String[] args) {
Integer[] arr = new Integer[]{3, 1, 2};
Arrays.sort(arr);//先排序 从小到大
System.out.println(Arrays.toString(arr));//[1, 2, 3]
System.out.println(Arrays.binarySearch(arr, 3));//2
}
}
copyOf
数组元素的复制
Integer[] newArr = Arrays.copyOf(arr , arr.length);
public class Test {
public static void main(String[] args) {
Integer[] arr = new Integer[]{1, 2, 3, 4, 5};
Integer[] newArr1 = Arrays.copyOf(arr, arr.length - 1);
System.out.println(Arrays.toString(newArr1));
//[1, 2, 3, 4]
Integer[] newArr2 = Arrays.copyOf(arr, arr.length + 1);
System.out.println(Arrays.toString(newArr2));
//[1, 2, 3, 4, 5, null]
}
}
- copyOf底层用的就是System.arraycopy(src , 0 , dest , 0 , 3 )
- 这个看下面的System类中有介绍
fill
数组元素的填充
Integer[] num =new lnteger[]{9,3,2};
Arrays.fill(num , 99);//num数组里面的所以值都被填充为99
Arrays.fill(Object[] ,fromeIndex,toIndex,val);
范围同样是左闭右开
- 想要修改某个区间内的值一般不使用fill()方法
public class Test {
public static void main(String[] args) {
Integer[] arr = new Integer[]{1, 2, 3, 4, 5};
Arrays.fill(arr, 99);
System.out.println(Arrays.toString(arr));
//[99, 99, 99, 99, 99]
Arrays.fill(arr,0,2,66);
System.out.println(Arrays.toString(arr));
//[66,66,99,99,99]
}
}
equals
比较两个数组元素内容是否完全一致
boolean equals = Arrays.equals(arr , arr2);
public class Test {
public static void main(String[] args) {
Integer[] arr1 = new Integer[]{1, 2, 3, 4, 5};
Integer[] arr2 = new Integer[]{1, 2, 3, 4, 5};
System.out.println(Arrays.equals(arr1, arr2));//true
}
}
重写了Object的equals方法,比较内容
asList
将数组转换成list集合
List
public class Test {
public static void main(String[] args) {
Integer[] arr1 = new Integer[]{1, 2, 3, 4, 5};
List<Integer> list = Arrays.asList(arr1);
System.out.println(list.size());//5
System.out.println(list.contains(1));//true
System.out.println(list.contains(6));//false
}
}
集合list中的方法可以调用,目前可以知道有 size()方法,返回数组的长度,有contains(int x)方法,判读array[x-1]是否存在,返回boolean值。
public class Test06TransactionByExecutor {
public static void main(String[] args) {
List<Car> cars = Arrays.asList(
new Car(null, "byd9", "black", 200000.0),
new Car(null, "byd10", "black", 200000.0),
new Car(null, "byd6", "black", 200000.0)
);
CarDao dao = new CarDao();
dao.savesByExecutor(cars);
}
}
System类
-
所属的包java.lang包 不需要导入
-
不需要创建对象 通过类名就可以访问
属性和方法
三个属性out in err
方法gc() exit(0); currentTimeMillis();
exit
退出当前程序
public class Test {
public static void main(String[] args) {
System.out.println("ok1");//ok1
System.exit(0);
System.out.println("ok2");//程序不会执行到这里的
}
}
arraycopy
public class Test {
public static void main(String[] args) {
int[] arr1 = new int[]{1, 2, 3, 4, 5};
int[] arr2 = new int[4];//[0, 0, 0, 0]
System.arraycopy(arr1, 0, arr2, 0, 3);
System.out.println(Arrays.toString(arr2));//[1, 2, 3, 0]
}
}
- 第一个参数:arr1是源数组
- 第二个参数:从源数组的哪个索引位置开始拷贝
- 第三个参数:arr2 是目标数组
- 第四个参数:把源数组的数据拷贝到 目标数组的哪个索引
- 第五个参数:把源数组拷贝多少个数据到目标数组(长度)
currentTimeMillis
返回当前系统时间 距离 1970 -1 -1的毫秒数差
public class Test {
public static void main(String[] args) {
long l = System.currentTimeMillis();
System.out.println(l);//1664167236118这个数字在随时间变动而变大
}
//可以利用这个方法,显示程序运行的时间
//程序开始时候 利用
}
返回当前系统时间与计算机元年之间的毫秒数差
1970年1月1日0时0分0秒做为计算机元年
gc
运行垃圾回收机制,public static gc()
.
直接System.gc()
调用
//主程序(main函数)的最后一行,调用垃圾回收机制
System.gc()
日期相关
Date类
- 通常使用的是java.util包
- 导包 拿来使用 构建对象
- 通常使用无参数的构造方法 或者带long构造方法
Date类中常用的方法
before(); after();
setTime() getTime();----->long
compareTo();
-
-1 调用在前,参数在后
-
1调用在后,参数在前
-
0表示相等
Date date1 = new Date(1545364985172L);//15分钟之前的时间
Date date2 = new Date();//默认就是用当前的系统时间构建的date对象
System.out.println(date2);
//重写了toString 格林威治格式Fri Dec 21 12:12:12 CST 2018
boolean x = date1.before(date2);//date1是否在date2之前
boolean y = date1.after(date2);//date1是否在date2之后
//date对象中应该有一个long的属性 time
date1.setTime(1545365012877L);//设置date1的时间 毫秒值
long reTime= date1.getTime();//获取date1的时间 毫秒值
System.out.println(x+"--"+y);
System.out.println(date2.compareTo(date1));//按照顺序比较 -1调用在前参数在后 1刚好相反 0代表两个时间一致
可以处理一个Date日期的格式 ↓↓↓
DateFormat类
- 包java.text 需要导包使用
- 此类是一个抽象类 不能创建对象 需要子类来干活
- SimpleDateFormat类 是DateFormat的子类
- 调用带String参数的构造方法创建format对象
Date date1 = new Date();//当前系统时间
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String v = sdf.format(date1);//通过sdf对象将date1格式化成你描述的样子
System.out.println(v);
Calendar类 1.1版本
1.所属的包java.util 需要导包
2.有构造方法 用protected修饰的 通常访问不到 通常会调用默认的getInstance();
Calendar calendar = Calendar.getInstance();
Calendar类常用方法
after() before()
setTime() getTime()---->Date
getTimeInMillis()----time
getTimeZone()---TimeZone
Calendar里面包含一个date属性 可以操作date的某一个局部信息
set get
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR,2015);
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH);//从0开始数
int day = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(year+"--"+month+"--"+day);
TimeZone类
- java.util包
- 可以通过calendar对象.getTimeZone()获取 或 TimeZone.getDefault();
TimeZone类常用方法
tz.getID() ----> Asia/Shanghai
tz.getDisplayName() 中国标准时间
TimeZone tz = calendar.getTimeZone();
//TimeZone tz = TimeZone.getDefault();
System.out.println(tz);
System.out.println(tz.getID());
System.out.println(tz.getDisplayName());
String类
String类概述
String 类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例。也就是说,Java 程序中所有的双引号字符串,都是 String 类的对象
。String 类在 java.lang 包下,所以使用的时候不需要导包!
没有任何继承关系 实现三个接口Serializable, CharSequence, Comparable
String的不可变性
- 字符串不可变,它们的值在创建后不能被更改
- 虽然 String 的值是不可变的,但是它们可以被共享
- 字符串效果上相当于字符数组( char[] ),但是底层原理是字节数组( byte[] )
String类中包含一个private final char[] value;
体现在两个地方 长度及内容
长度--->final修饰的数组 数组长度本身不变 final修饰数组的地址也不变
内容--->private修饰的属性并且没有提供方法 不能在类的外部访问
String类的构造方法
-
常用的构造方法(创建对象)
方法名 说明 public String() 创建一个空白字符串对象,不含有任何内容 public String(char[] chs) 根据字符数组的内容,来创建字符串对象。 将字符数组变成字符串
public String(byte[] bys) 根据字节数组的内容,来创建字符串对象。 将字节数组变成字符串
String s = “abc”; 直接创建 public String(char[] chs,int offset, int count) 从offset号索引开始存往后一共存count个
public String(byte[] chs,int offset, int count) 从offset号索引开始存往后一共存count个
-
示例代码
public class TestUtil { public static void main(String[] args) { //public String():创建一个空白字符串对象,不含有任何内容 String s1 = new String(); System.out.println("s1:" + s1); //public String(char[] chs):根据字符数组的内容,来创建字符串对象 char[] chs = {'a', 'b', 'c', 'd', 'e'}; String s2 = new String(chs); System.out.println("s2:" + s2); String s3 = new String(chs, 1, 3);从1号索引开始存往后一共存3个 System.out.println("s3:" + s3);//bcd //public String(byte[] bys):根据字节数组的内容,来创建字符串对象 byte[] bys = {97, 98, 99}; String s4 = new String(bys); System.out.println("s4:" + s4); //String s = “abc”; 直接赋值的方式创建字符串对象,内容就是abc String s5 = "abc"; System.out.println("s5:" + s5); } }
创建字符串对象两种方式的区别
-
通过构造方法创建
通过 new 创建的字符串对象,每一次 new 都会申请一个内存空间,虽然内容相同,但是地址值不同
-
字符串存储的内存原理
String s1 = “abc”;直接赋值
特点:
此时字符串abc是存在字符串常量池中的。
先检查字符串常量池中有没有字符串abc,只要字符序列相同(顺序和大小写),无论在程序代码中出现几次,JVM 都只会建立一个 String 对象,并在字符串池中维护。如果相同,不会创建新的,而是直接复用。如果没有abc,才会创建一个新的。
s1记录的是字符串常量池中的地址值。
所以,直接赋值的方式,代码简单,而且节约内存。
-
new出来的字符串
看到new关键字,一定是在堆里面开辟了一个小空间。
String s2 = new String(“abc”);
通过 new 创建的字符串对象,每一次 new 都会申请一个内存空间,虽然内容相同,但是地址值不同.
字符串的比较
-
示例代码
public class TestString { public static void main(String[] args){ //String类 "abc"对象 常量区 String s1 = "abc"; String s2 = "abc"; String s3 = new String("abc"); String s4 = new String("abc"); System.out.println(s1==s2);//true System.out.println(s1==s3);//false System.out.println(s3==s4);//false System.out.println(s1.equals(s2));//true String类将继承自Object中的equals方法重写啦 System.out.println(s1.equals(s3));//true 将原有比较==的方式改为比较字符值 System.out.println(s3.equals(s4));//true } }
内存图
String常用方法
equals()
boolean = equals(Object obj);
继承自Object String重写啦
- 参数 : Object obj
- 返回值类型 : boolean类型
- 作用 : 比较两个字串中的字面值是否相等
equalsIgnoreCase() 方法
-
用于将字符串与指定的对象比较
-
不考虑大小写
代码示例
public class TestString {
public static void main(String[] args){
//String类 "abc"对象 常量区
String s1 = "abc";
String s2 = "abc";
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s1.equals(s2));//true String类将继承自Object中的equals方法重写啦
System.out.println(s1.equals(s3));//true 将原有比较==的方式改为比较字符值
System.out.println(s3.equals(s4));//true
}
}
- String重写了Object中的equals()方法比较两个字串中的内容是否相等
- StringBuilder继承Object中的equals()方法比较两个字串的地址
hashCode()
int = hashCode();
//继承自Object 重写啦
- 参数 : 无
- 返回值类型 : int类型
- 作用 : 将当前字符串的每一个char元素拆开 乘以31求和
String str = "abc";
str.hashCode();// 内存地址调用一个本地的native方法进行计算
"abc" h=0
h = (0*31+97)
h = (97)*31+98
h = ((97)*31+98)*31+99
compareTo()
int = compareTo(String str);
//实现自Comparable接口 实现啦 按照字典(Unicode编码)索引的顺序比较
- 参数 : String str
- 返回值类型 : int类型
- 按照两个字符串长度较短的那个作为比较循环的次数
- 挨个比元素 str[i]-str[i] 循环内如果有结果 就返回结果
按照字典索引比较code码的值,不为零直接返回结果
- 如果循环过程后发现所有的字符都一样 len1-len2 注意
循环的次数是字符串短的长度,在循环内两个字符串相同
- 返回0表示两个字符相等
public class TestUtil {
public static void main(String[] args) {
String s1 = "dbc";
String s2 = "ab";
System.out.println(s1.compareTo(s2));//3
String s3 = "ab";
String s4 = "ab";
System.out.println(s3.compareTo(s4));//0
String s5 = "ab";
String s6 = "abd";
System.out.println(s5.compareTo(s6));//-1
}
}
toString()
String = toString();
//继承自Object 重写啦 不再输出 类名@hashCode 字符串中的字面值
public class TestUtil {
public static void main(String[] args) {
String s1 = "abc";
System.out.println(s1.toString());//abc
}
}
根据索引得字符
- char = charAt(int number)
- 获取某个索引位置处的字符
public class StringAPI {
public static void main(String[] args) {
String name = "我爱你中国love";
// 2、public char charAt(int index): 获取某个索引位置处的字符
System.out.println("字符串为:" + name);
System.out.print("索引1位置的字符为:");
char c = name.charAt(1);
System.out.println(c);//爱
System.out.println("------------遍历字符串中的每个字符--------------");
for (int i = 0; i < name.length(); i++) {
char ch = name.charAt(i);
System.out.print(ch + "\t");
}
}
}
根据索引查code码
- int = codePointAt(int index);//"abc" 0-->97
- 返回给定index对应位置的那个char所对应的code码
public class TestUtil {
public static void main(String[] args) {
String str1 = "abc";
int num = str1.codePointAt(0);//"abc" 0-->97
System.out.println(num);//97
}
}
根据元素查索引
- int = indexOf(String str [,int fromIndex]); 从左边开始找
- int = lastIndexOf(String str [,int fromIndex]) 从右边开始找
- 找寻给定的str在字符串中第一次出现的索引位置 带重载 则从某一个位置开始找
public class TestUtil {
public static void main(String[] args) {
String s = "abcdecfaq";
System.out.println(s.indexOf("c"));//2
System.out.println(s.indexOf("c", 4));//5
System.out.println(s.lastIndexOf("a"));//7
System.out.println(s.lastIndexOf("a", 1));//0
}
}
截取字符串
substring(int x, int x)
截取内容(包前不包后的)
public class StringAPI {
public static void main(String[] args) {
// 4、public String substring(int beginIndex, int endIndex) :截取内容,(包前不包后的)
String name = "Java是最厉害的编程语言!";
// 0123 45 67 8 9
String rs = name.substring(0, 9);//和数组一样从0开始哦 也就是说 0 的位置代表 J
System.out.println(rs);
String rs = name.substring(4, 9);
System.out.println(rs);
}
}
对象.substring(a,b),截取的范围是[a,b)
分割字符串成数组
-
String[] = split() 按照某个内容把字符串分割成字符串数组返回
-
如果用"."作为分隔的话,必须是如下写法,String.split("\."),这样才能正确的分隔开,不能用String.split(".")。
-
如果用“|”作为分隔的话,必须是如下写法,String.split("\|"),这样才能正确的分隔开,不能用String.split("|"),“.”和“|”都是转义字符,必须得加"\"。
public class StringAPI {
public static void main(String[] args) {
// 9、public String[] split(String s): 按照某个内容把字符串分割成字符串数组返回。
String name = "王宝强,贾乃亮,陈羽凡";
String[] names = name.split(",");
for (int i = 0; i < names.length; i++) {
System.out.println("选择了:" + names[i]);
/*选择了:王宝强
选择了:贾乃亮
选择了:陈羽凡*/
}
}
}
替换字符串
String = replace(String s1 , String s2)
- replace();
- replaceAll();支持正则表达式
- replaceFirst(); 换第一次出现的那个字串
将给定的字符串替换成另外的字符串
public class StringAPI {
public static void main(String[] args) {
// 6、public String replace(CharSequence target, CharSequence replacement)
String name = "金三胖是最厉害的80后,金三胖棒棒的!我好爱金三胖";
//将字符串中的字替换成想要的字符串
String rs = name.replace("金三胖", "***");
System.out.println(rs);//***是最厉害的80后,***棒棒的!我好爱***
}
}
一定要用变量接收或者直接打印输出,不然不生效
获取字符串长度
int = length();
- 参数 : 无
- 返回值类型 : int类型
- 作用 : 得到字符串的长度
代码示例:
public class StringAPI {
public static void main(String[] args) {
// 1、public int length(): 获取字符串的长度 ``
String name = "我爱你中国love";
System.out.println(name.length());//9
}
}
字符串拼接
String = concat(String);
//将给定的字符串拼接在当前字符串之后
public class TestUtil {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "def";
String s3 = str1.concat(str2);
System.out.println(s3);//abcdef
}
}
String str = "a";
long time1 = System.currentTimeMillis();
for(int i=1;i<=200000;i++){
//str+="a";//每一次利用+在原来的字符串后面拼接一个新的a + 9447毫秒
//str = str.concat("a");//利用concat拼接字符 5324毫秒
//StringBuffer对象 拼接效率非常高 像以前自己封装的ArrayBox
}
long time2 = System.currentTimeMillis();
System.out.println(time2-time1);
判断是否有存在
boolean = contains(String s)
判断字符串中有没有存在
public class StringAPI {
public static void main(String[] args) {
String name = "金三胖是最厉害的80后,金三胖棒棒的!我好爱金三胖";
// 7、public boolean contains(CharSequence s)
// 判断字符串中有没有包含
System.out.println(name.contains("金三胖")); // true
System.out.println(name.contains("金二胖")); // false
}
}
删除空白符
- trim()方法
- 用于删除字符串的头尾空白符。
public class Test {
public static void main(String args[]) {
String Str = new String(" 王志鹏 ");
System.out.print("原始值 :");
System.out.println(Str);// 王志鹏
System.out.print("删除头尾空白 :");
System.out.println(Str.trim());//王志鹏
}
}
字符串转字节数组
byte[] = getBytes(); ---> getBytes(String charsetName);
- getBytes(String charsetName): 使用指定的字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
- getBytes(): 使用平台的默认字符集将字符串编码为 byte 序列,并将结果存储到一个新的 byte 数组中。
- charsetName -- 支持的字符集名称。
public class Test {
public static void main(String args[]) {
String Str1 = "wzp";
byte[] Str2 = Str1.getBytes();
for (byte b : Str2) {
System.out.println(b);//119 122 112
}
}
}
public class Test {
public static void main(String args[]) {
String Str1 = new String("runoob");
try{
byte[] Str2 = Str1.getBytes();
System.out.println("返回值:" + Str2 );
Str2 = Str1.getBytes( "UTF-8" );
System.out.println("返回值:" + Str2 );
Str2 = Str1.getBytes( "ISO-8859-1" );
System.out.println("返回值:" + Str2 );
} catch ( UnsupportedEncodingException e){
System.out.println("不支持的字符集");
}
}
}
字符串转字符数组
char[] = toCharArray()
public class StringAPI {
public static void main(String[] args) {
String name = "我爱你中国love";
// 3、public char[] toCharArray():: 把字符串转换成字符数组
char[] chars = name.toCharArray();
for (int i = 0; i < chars.length; i++) {
char ch = chars[i];
System.out.println(ch);
}
}
}
各种类型转字符串
- String.valueOf(Object obj)
String s1 = String.valueOf(1);
String s2 = String.valueOf('c');
- 后面加""
String s1 = 1 + "";
String s2 = 'c' + "";
匹配正则表达式
matches()
public class Test {
public static void main(String args[]) {
String Str = new String("www.runoob.com");
System.out.print("返回值 :");
System.out.println(Str.matches("(.*)runoob(.*)"));//true
System.out.print("返回值 :");
System.out.println(Str.matches("(.*)google(.*)"));//false
System.out.print("返回值 :");
System.out.println(Str.matches("www(.*)"));//true
}
}
判断是否初字符串
boolean = startsWith(String s)
判断是不是开始的字符串
public class StringAPI {
public static void main(String[] args) {
String name = "金三胖是最厉害的80后,金三胖棒棒的!我好爱金三胖";
// 8、public boolean startsWith(String prefix)
// 判断是不是开始的字符串,判断结果范围 true或者false
System.out.println(name.startsWith("金三胖"));//true
System.out.println(name.startsWith("金三胖是最厉害的"));//true
System.out.println(name.startsWith("金三胖是最厉害的2"));// false
}
}
判断是否末字符串
endsWith(String suffix);
判断此字符串是否已xx开头/结尾
public class StringAPI {
public static void main(String[] args) {
String name = "金三胖是最厉害的80后,金三胖棒棒的!我好爱金三胖";
System.out.println(name.endsWith("我好爱金三胖"));//true
}
}
判断是否空字符串
boolean = isEmpty();
判断当前字符串是否为空字符串 (length是否为0)
public class TestUtil {
public static void main(String[] args) {
String s1 = "null";
String s2 = "";
System.out.println(s1.isEmpty());//false
System.out.println(s2.isEmpty());//true
}
}
String s1 = "null"; s1不是空字符串
小写变大写
- toUpperCase()
- 返回转换后字符的大写形式,如果有大写的话;否则返回该字符本身。
public class Test {
public static void main(String args[]) {
String name = "wZp";
System.out.println(name.toUpperCase());//WZP
System.out.println(Character.toUpperCase('c'));//C
}
}
大写变小写
- toLowerCase()
- 转换为小写的字符串。如果有小写的话;否则返回该字符本身。
public class Test {
public static void main(String args[]) {
String Str1 = new String("WZP");
String Str2 = new String("WzP");
System.out.println(Str1.toLowerCase());//wzp
System.out.println(Str2.toLowerCase());//wzp
}
}
总结
- 第一梯队(重写)
equals hashCode compareTo toString
- 第二梯队(常用)
charAt() codePointAt()
indexOf() lastIndexOf()
substring() split() replace()
length() concat() contains(); trim();
getBytes() toCharArray() matches()
- 第三梯队(一般)
toUpperCase() toLowerCase()
startsWith() endsWith();
isEmpty();
StringBuilder类
-
StringBuffer jdk1.0
同步线程
安全 -
StringBuilder jdk1.5 多线程问题
非同步线程
速度快 可能存在安全问题
1.所属的包 java.lang包
2.继承AbstractStringBuilder 间接继承 Object
- 实现接口Serializable,CharSequence,Appendable
- StringBuffer/StringBuilder没有compareTo方法
- StringBuffer/StringBuilder含有一个String没有的方法 append();拼接
特性
StringBuilder 可以看成是一个容器,创建之后里面的内容是可变的。
当我们在拼接字符串和反转字符串的时候会使用到
可变字符串 char[] value; 动态扩容
对象的构建
//无参数构造方法 构建一个默认长度16个空间的对象 char[]
StringBuilder builder = new StringBuilder();
//利用给定的参数 构建一个自定义长度空间的对象 char[]
StringBuilder builder = new StringBuilder(20);
//利用带String参数的构造方法 默认数组长度字符串长度+16个
StringBuilder builder = new StringBuilder("abc");
StringBuilder常用的方法
拼接字符串
最主要的方法 append() 频繁的拼接字符串的时候使用此方法 提高性能
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("a");//17
long time1 = System.currentTimeMillis();
for (int i = 1; i <= 200000; i++) {
builder.append("a");//可以拿变量接收也可以不用变量接收,一般不用接收就行了
}
long time2 = System.currentTimeMillis();
System.out.println(time2 - time1);
}
}
插入"元素"
- insert(int index,value); 将给定的value插入在index位置之上
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
builder.insert(1, "n");
System.out.println(builder);//anbcdefg
}
}
删除"元素"
StringBuilder = delete(int start ,int end);
- StringBuilder类中独有的方法String类没有
- 将start到end之间的字符串删掉 不用接受返回值就看到效果啦
StringBuilder = deleteCharAt(int index);
- String类中没有delete(int start ,int end)方法
- 将给定index位置的某一个字符删除掉啦`
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
builder.deleteCharAt(2);
System.out.println(builder);//abdefg
builder.delete(2, 5);
System.out.println(builder);//abg
}
}
字符串反转
- reverse()
- 将字符串反转
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
builder.reverse();
System.out.println(builder);//gfedcba
}
}
toString()
- toString()
- 将StringBuilder对象 构建成一个string对象 返回
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
String s1 = builder.toString();
System.out.println(s1);//abcdefg
}
}
- 还有一个方法是用String的构造方法也可以
- new String(new StringBuilder(str).reverse());
字符串长度
- length();//字符串有效元素个数(长度)
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
System.out.println(builder.length());//7 有效元素的个数
}
}
根据索引查元素"
- char = charAt(int index);
- 给一个索引号返回对应的字符
- int = codePointAt(int index);
- 给一个索引号返回对应的code码
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
System.out.println(builder.charAt(0));//a
System.out.println(builder.codePointAt(0));//97
}
}
根据元素查索引
- int = indexOf(String str [,int fromIndex]); 从左边开始找
- int = lastIndexOf(String str [,int fromIndex]) 从右边开始找
- 找寻给定的str在字符串中第一次出现的索引位置 带重载 则从某一个位置开始找
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdecfaq");
System.out.println(builder.indexOf("c"));//2
System.out.println(builder.indexOf("c", 4));//5
System.out.println(builder.lastIndexOf("a"));//7
System.out.println(builder.lastIndexOf("a", 1));//0
}
}
**如果找不到 返回return -(1+low) low是元素本该出现的位置**
截取字符串
- String = substring(int start ,int end);
- 截取字符串
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
String value1 = builder.substring(2, 5);//2索引开始5索引结束
String value2 = builder.substring(2);//2索引开始截取到结束
System.out.println(value1);//cde
System.out.println(value2);//cdefg
}
}
注意需要接受返回值 看见截取出来的新字符串效果
替换元素
- replace(int start,int end,String str);
- 将start和end之间的部分替换成str
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
builder.replace(2, 5, "wzp");
System.out.println(builder);//abwzpfg
}
}
设置底层数组长度
- ensureCapacity(int minimumCapacity) 确保底层数组容量够用
不常用
- capacity() 底层那个数组的容量
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
System.out.println(builder.capacity());//底层那个数组的容量7+16
builder.ensureCapacity(50);
System.out.println(builder.capacity());//50
}
}
设置字符串有效长度
- setLength();
- 设置字符串的有效元素个数
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
System.out.println(builder.length());//7
System.out.println(builder.capacity());//23
builder.setLength(20);
System.out.println(builder.length());//20
System.out.println(builder.capacity());//23
}
}
清除数组无用容量
- trimToSize()
- 将数组中无用的容量去掉 变成length长度的数组
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
System.out.println(builder.capacity());//7+16
builder.trimToSize();
System.out.println(builder.capacity());//7
builder.setLength(20);
System.out.println(builder.capacity());//20
}
}
设置"元素"
- setCharAt(int index,char value);
- 将index位置的字符改成给定的value
public class TestUtil {
public static void main(String[] args) {
StringBuilder builder = new StringBuilder("abcdefg");
builder.setCharAt(0, 'w');
System.out.println(builder);//wbcdefg
}
}
知识总结
1.StringBuilder类一般是为了避免String频繁拼接修改字符串信息的时候才用的 , 因为底层数组是可变的 , 提高了性能
- 常用方法
与String类不同的独有方法
append() insert() delete() deleteCharAt() reverse()
与String类相同的方法
length() charAt() codePointAt() indexOf() lastIndexOf()
substring() replace()名字相同 用法不一致
- 不是很常用的方法
ensureCapacity() capacity() setLength() trimToSize(); setCharAt();
链式编程
public class StringBuilderDemo4 {
public static void main(String[] args) {
//1.创建对象
StringBuilder sb = new StringBuilder();
//2.添加字符串
sb.append("aaa").append("bbb").append("ccc").append("ddd");
//链式编程:依赖前面方法的结果,再去调用后面的结果
System.out.println(sb);//aaabbbcccddd
//3.再把StringBuilder变回字符串
String str = sb.toString();
System.out.println(str);//aaabbbcccddd
}
}
练习1:对称字符串
需求:
键盘接受一个字符串,程序判断出该字符串是否是对称字符串,并在控制台打印是或不是
对称字符串:123321、111
非对称字符串:123123
代码示例:
public class StringBuilderDemo6 {
//使用StringBuilder的场景:
//1.字符串的拼接
//2.字符串的反转
public static void main(String[] args) {
//1.键盘录入一个字符串
Scanner sc = new Scanner(System.in);
System.out.println("请输入一个字符串");
String str = sc.next();
//2.反转键盘录入的字符串
String result = new StringBuilder().append(str).reverse().toString();
//3.比较
if(str.equals(result)){
System.out.println("当前字符串是对称字符串");
}else{
System.out.println("当前字符串不是对称字符串");
}
}
}
练习2:拼接字符串
需求:定义一个方法,把 int 数组中的数据按照指定的格式拼接成一个字符串返回。
调用该方法,并在控制台输出结果。
例如:数组为int[] arr = {1,2,3};
执行方法后的输出结果为:[1, 2, 3]
代码示例:
package com.itheima.stringbuilderdemo;
public class StringBuilderDemo7 {
public static void main(String[] args) {
//1.定义数组
int[] arr = {1,2,3};
//2.调用方法把数组变成字符串
String str = arrToString(arr);
System.out.println(str);
}
public static String arrToString(int[] arr){
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < arr.length; i++) {
if(i == arr.length - 1){
sb.append(arr[i]);
}else{
sb.append(arr[i]).append(", ");
}
}
sb.append("]");
return sb.toString();
}
}
StringJoiner
- StringJoiner跟StringBuilder一样,也可以看成是一个容器,创建之后里面的内容是可变的。
- 作用:提高字符串的操作效率,而且代码编写特别简洁,但是目前市场上很少有人用。
- JDK8出现的
基本使用:
//1.创建一个对象,并指定中间的间隔符号
StringJoiner sj = new StringJoiner("---");// ---为间隔符号
//2.添加元素
sj.add("aaa").add("bbb").add("ccc");
//3.打印结果
System.out.println(sj);//aaa---bbb---ccc
//1.创建对象
StringJoiner sj = new StringJoiner(", ","[","]");// ,为间隔符号 [ 为开始符号 ] 为结束符号
//2.添加元素
sj.add("aaa").add("bbb").add("ccc");
int len = sj.length();
System.out.println(len);//15
//3.打印
System.out.println(sj);//[aaa, bbb, ccc]
String str = sj.toString();
System.out.println(str);//[aaa, bbb, ccc]
常见面试题:
==和equals
-
==号比较的到底是什么?
如果比较的是基本数据类型:比的是具体的数值是否相等。
如果比较的是引用数据类型:比的是地址值是否相等。
结论:==只能用于比较基本数据类型。不能比较引用数据类型。
-
"=="与"equals"到底有哪些区别?
equals的底层是Object(父类)如下:
他在默认的情况下就是在比较两个对象内存地址是否一样
public boolean equals (Object obj){
return (this==obj);
}
在String,Date,Integer等一系列的类当中重写了Object的equals方法,比较的是内容是具体的数值是否相等
不是重写之后就一定比较的是具体值,而是要看具体的重写的规则了
public boolean equals(Object anObject) {
// 判断要比较的字符串与当前字符串的引用是否相等
// 引用相等,返回true
if (this == anObject) {
return true;
}
// 此时引用不等,判断要比较的对象是否是String对象
// 不是的话直接返回false
if (anObject instanceof String) {
// 强转为String
String anotherString = (String) anObject;
int n = value.length;
// 比较两个字符串的长度是否相等
// 如果长度不想等的话就没有比较的必要
if (n == anotherString.value.length) {
//长度相等,比较字符串中的每个字符是否相等
// 如果有一个不相等,则直接返回false
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
在使用String的时候,为什么在比较两个String值是否一样呢,这是因为他底层重写了equals方法
在比较两个String底层里面数组内容值是否一样的会做一个循环比较,如果一样的情况下就返回true
如果自己去自定义一个java对象,想去比较两个java对象成员属性值是否一样的情况下注意在没有重写equals方法
的时候,他是在默认比较两个对象内存地址是否一样,如果重写了之后就是在比较两个对象成员属性值是否一样如果一样就返回true,这样的话,才是真正在比较我们的两个对象成员属性值是否一样。
为什么重写了equals方法还需要去重写hashcode方法?
如果重写了equals方法他是有定律的,也就是说当两个对象他如果在做比较的时候通过equals如果返回true的情况下
说明他们的hashcode的值一定是一样的,反过来,如果两个对象他的值完全不一样 , 那有可能hashcode值的相同的
该过程也就是哈希冲突,举个例子 当前使用一个字母的一个a和英黑格97,你会发现,他们的hashcode值完全相同
但是内容值不一样,所以有给定律是这样说的,也就是说如果两个对象使用equals比较返回true的情况下
则hashcode值相同,如果在这一块只重写了equals方法,没有重写hashcode,是有可能equals为ture
两个hashcode值是不一样的那就违背了定律,所以一定要重写hashcode,而且像一些集合框架源码底层里面
比如hashmap底层,它的底层里面再往里面翻,是不是在通过我们的这个hashcode来做比较
如果只重写了equals方法,没有重写hashcode,在以后我们存读的时候,数据会有问题的
String所属的包 继承关系 实现接口
java.lang 继承Object 接口Serializable,CharSequence,Comparable
String构建方式
常量 构造方法
String对象内存结构
字符串常量区 new堆内存对象
== equals()区别
"a"+"b"+"c"
String str = "a"+"b"+"c"+"d";//数学计算 拼接符号
// System.out.println(str);//过程中产生了几个String对象? 字符串常量池7个
// //1对象-->value[] a "a"
// //2对象-->value[] b "b"
// //3对象-->value[] {a,b} "ab"
// //4对象-->value[] c "c"
// //5对象-->value[] {a,b,c} "abc"
// //6对象-->value[] d "d"
// //7对象-->value[] "abcd"
String不可变特性
长度及内容
String中的常用方法---与StringBuilder的区别
concat(); toUpperCase();
String和StringBuilder区别 | String和StringBuffer区别
String不可变字符串
JDK1.0
有一个接口Comparable
不可变体现在长度及内容
有一些方法StringBuilder没有 concat compareTo toUpperCase
StringBuilder可变字符串
JDK1.5
有一个接口Appendable
可变字符串 没有final修饰 底层可以进行数组扩容
有一些方法String没有 append() insert() delete() reverse()
StringBuffer和StringBuilder的不同
StringBuffer早期版本1.0
StringBuilder后来的版本1.5
早期版本 线程同步 安全性比较高 执行效率相对较低
后期版本 线程非同步 安全性比较低 执行效率相对较高
正则表达式
正则表达式概念
- 一个带有一定规律的表达式
- 匹配字符串格式的
正则表达式作用
- 字符串的格式校验 String类中提供的一个方法 boolean = str.matches("regex");
- 字符串的拆分及替换 String类中提供的方法replace split
- 字符串的查找 Pattern模式 Matcher匹配器
如下的所有都用来描述字符的信息
[abc] abc其中的一个
[^abc] 不能是abc其中的一个 其他都可以
[a-zA-Z] 表示必须是这两个范围内的
[a-z&&[^bc]] 表示a-z其中的一个但不能是b和c
| 或者
. 代表任意一个字符
\d digit数字 [0-9]
\D 非数字 [^0-9]
\s space留白 一个空格 一个回车 一个换行。。。
\S 非留白
\w word单词 [0-9A-Za-z] 数字或字母都可以
\W 非单词 [^0-9A-Za-z]
如下的所有都用来描述字符出现的次数
? 0-1次 [0-9]?
* 0-n次
+ 1-n次
{n} 固定n次
{n,} 至少出现n次
{m,n} m~n次
代码示例
package regexp;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TestRegex {
public static void main(String[] args){
// Scanner input = new Scanner(System.in);
// System.out.println("请您输入一个字符串");
// String str = input.nextLine();
//判断输入的str字符串内容是否满足什么样的格式
//第一个字母必须是a 第二个字母是abc其中的一个
// boolean result1 = str.matches("a[abc]");
// System.out.println(result1);
//第一个字母必须是a 第二个字母是非abc任意的其他一个
// boolean result2 = str.matches("a[^abc]");
// System.out.println(result2);
//第一个任意 第二个26字母大小写范围之内的一个字母
// boolean result = str.matches(".[a-zA-Z]");
// System.out.println(result);
//a-z都可以 不能是b和c
// boolean result = str.matches("[a-z&&[^bc]]");
// System.out.println(result);
// String value = "a,b+c#d";
// String[] result = value.split(",|\\+|#");
// System.out.println(result.length);
//所有的字串中找寻满足如下规则的信息 邮政编码
String str = "123456abc222333abc654321abc";
//1.利用Pattern类创建一个模式 理解为是一个正则表达式对象
Pattern pattern = Pattern.compile("\\d{6}");//邮编
//2.需要提供一个字符串
//3.利用pattern模式对象创建一个匹配器
Matcher matcher = pattern.matcher(str);
//4.找寻字符串中出现满足上述格式的字串
while(matcher.find()){//判断str是否满足规则
System.out.println(matcher.group());//找到满足字符串格式的那一串文字
}
}
}