第七章 常用类
7.1 String
7.1.1 String类是不可变类
- 就是string对象创建后不可以修改
- 案例:
public class Demo {
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
s1 = s1 +s2;
System.out.println(s1);
}
}

- 从上面图可以看到string对象赋值后不能再修改了,这就是不可变对象,如果对字符串修改,那么将会创建新的对象。
- 注意:只要使用双引号赋值的字符串,那么在编译期将会放到方法区的常量池中,如果是运行时对字符串拼接那么会放到堆区中
- 常量池中不允许出现重复的对象
7.1.2 String s1 = new String("abc");
- 创建了2个对象,分别在堆和常量池,返回堆中的地址
public class Demo {
public static void main(String[] args) {
/**
在堆中必须创建一个对象,并且返回的地址就是堆中对象的地址,
但是,常量池也会创建一个对象,如果常量池中已经存在了abc对象,那么,就不再创建了
*/
String s2 = new String("abc");
}
}

7.1.3 一共创建了3个对象
public class Demo {
public static void main(String[] args) {
String s1 = "abc";
String s2 = new String("abc");
String s3 = new String("abc");
}
}
- 堆中创建了2个对象,常量池中创建了1个对象


7.2 String的常用方法
7.2.1 使用测试方法:单元测试junit
- 创建源码测试包

- 编写测试方法
public class Demo {
//编写一个方法
public int sum(int i,int n){
return i+n+1;
}
}
import com.Demo;
import junit.framework.TestCase;
public class DemoTest extends TestCase {
//测试方法
public void test1(){
Demo demo = new Demo();
int sum = demo.sum(1,1);
System.out.println(sum);
}
}
- 可以使用断言进行逻辑测试

7.2.2 字符串常用方法
import junit.framework.TestCase;
public class DemoTest extends TestCase {
//toCharArray:把字符串转为字符数组
public void test1(){
String s1 = "abc";
//转为数组
char[] array = s1.toCharArray();
//循环
for (int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
//charAt方法:根据字符索引返回
public void test2(){
String s = "abc";
char c = s.charAt(1);
System.out.println(c);
}
//codePointAt返回对应字符的unicode码
public void test3(){
String s = "abc";
int i = s.codePointAt(0);
System.out.println(i);
}
//concat拼接字符串
public void test4() {
String s = "abc";
System.out.println(s + "hello");
//使用方法
System.out.println(s.concat("java"));
}
//contains是否包含指定的字符串
public void test5(){
String s = "abc";
System.out.println(s.contains("ab"));
System.out.println(s.contains("cd"));
}
//endsWith判断字符串是否含有指定的后缀
public void test6() {
String s = "abc";
System.out.println(s.endsWith("c"));
System.out.println(s.endsWith("abc"));
System.out.println(s.endsWith("bc"));
}
//startsWith判断字符串是否含有指定的前缀
public void test7(){
String s = "abc";
System.out.println(s.startsWith("c"));
System.out.println(s.startsWith("abc"));
System.out.println(s.startsWith("bc"));
}
//equalsIgnoreCase比较值时不区分大小写
public void test8(){
String s1 = "abc";
String s2 = "ABC";
System.out.println(s1.equals(s2));
System.out.println(s1.equalsIgnoreCase(s2));
//原理
System.out.println(s1.toLowerCase().equals(s2.toLowerCase()));
}
//getBytes() 转为字节数组
public void test9(){
String s1 = "abc";
byte[] bytes = s1.getBytes();
for (int i = 0; i < bytes.length;i++) {
System.out.println(bytes[i]);
}
}
//hashCode获取哈希码
public void test10(){
String s1 = "abc";
System.out.println(s1.hashCode());
}
//indexOf获取指定字符或字符串第一次出现的位置(下标)
public void test11(){
String s1 = "hello";
System.out.println(s1.indexOf("l"));
}
//lastIndexOf获取指定字符或字符串最后一次出现的位置(下标)
public void test12(){
String s1 = "hello";
System.out.println(s1.lastIndexOf("l"));
}
//可以获取文件的扩展名称
public void test13(){
String s1 = "java.txt";
System.out.println(s1.lastIndexOf("."));
}
//subString截取字符串
public void test14(){
String s1 = "java.txt";
//修改文件名称
int index = s1.lastIndexOf(".");
//截取
String name = s1.substring(index);
//新名称
name = UUID.randomUUID()+name;
System.out.println(name);
}
//subString截取字符串
public void test15(){
String s1 = "hadoop";
//左闭右开
System.out.println(s1.substring(1,3));
}
//isEmpty() 是否为空
public void test16(){
String s1 = "hadoop";
System.out.println(s1.isEmpty());
}
//jion拼接
public void test17(){
//第一个参数表示分隔符号
String str = String.join(";","a","b","c");
System.out.println(str);
}
//length()获取字符串长度的方法
public void test18(){
String s = "abc";
System.out.println(s.length());
}
//replace替换
public void test19(){
String s = "aaa111ggggg666666sssssss77777";
String replace = s.replace("7", "");
System.out.println(replace);
}
public void test20(){
String uuid = UUID.randomUUID().toString();
System.out.println(uuid);
System.out.println(uuid.replace("-",""));
}
//replaceAll替换:可以使用正则表达式
public void test21(){
String s = "aaa111ggggg666666sssssss77777";
//System.out.println(s.replace("77777","好"));
System.out.println(s.replaceAll("7{5}","好"));
}
public void test22(){//将数字替换为好
String s = "aaa111ggggg666666sssssss77777";
System.out.println(s.replaceAll("\\d","好"));
}
public void test23(){//将非数字替换为好
String s = "aaa111ggggg666666sssssss77777";
System.out.println(s.replaceAll("\\D","好"));
}
//split按照指定分隔符号返回字符串数组
public void test24(){
String s = "hello;java;hbase;hive;flink";
String[] array = s.split(";");
for (int index = 0; index < array.length; index++) {
System.out.println(array[index]);
}
}
public void test25(){//可以使用正则表达式
String s = "hello;java,hbase.hive:flink";
String[] array = s.split("\\W");
for (int index = 0; index < array.length; index++) {
System.out.println(array[index]);
}
}
//toUpperCase转为大小写
public void test26(){//可以使用正则表达式
String s = "hello";
System.out.println(s.toUpperCase());
String s1 = "ABC";
System.out.println(s1.toLowerCase());
}
//toString转为字符串
public void test27(){
UUID uuid = UUID.randomUUID();
//转字符串
System.out.println(uuid.toString());
}
//valueOf转为字符串
public void test28(){
int n = 1000;
String s = String.valueOf(n);
System.out.println(s);
}
}
7.3 StringBuffer和StringBuilder
7.3.1 StringBuffer
- StringBuffer和StringBuilder称为字符串缓冲区;原理:预先申请一块内存存储字符序列,如果存满了,会重新改变缓冲区的大小,以容纳更多的字符串。
- StringBuffer是可变对象,String是不可变对象,这是它们最大的区别
- 以后在拼接字符串时就不能使用string而是使用StringBuffer或StringBuilder
7.3.2 不能这样拼接字符串
public class DemoTest {
@Test
public void test1(){
String str = "";
for (int i = 0; i < 10; i++) {
//这种拼接字符串的方式会产生大量垃圾对象
str += i;
}
System.out.println(str);
}
}
7.3.3 推荐使用StringBuilder拼接字符串
public class DemoTest {
@Test
public void test1(){
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10; i++) {
//推荐使用
sb.append(i);
}
System.out.println(sb);
}
}
7.3.4 StringBuffer区别StringBuilder
7.3.4.1 StringBuffer
- 是线程安全的,就是多线程的
- 效率比较低
- 源代码

7.3.4.2 StringBuilder
- 单线程,可以使用在方法中,使之成为局部变量就安全了(栈帧间不通信)
- 执行效率高
- 源代码

7.3.5 StringBuffer源代码
- 初始化的长度:16个字符

- 扩容的容量

- 最大的容量

7.3.5.1 笔试题
- StringBuilder stringBuilder = new StringBuilder(20);扩容了几次?
答:扩容了0次

7.3.6 StringBuilder中的常用方法
- 使用deleteCharAt
public class DemoTest {
@Test
public void test1(){
StringBuilder sb = new StringBuilder();
//拼接数字
for (int i = 0; i < 10; i++) {
sb.append(i).append(",");
}
去掉最后一个逗号
sb.deleteCharAt(sb.toString().length()-1);
System.out.println(sb);
}
}
- 字符串截取
public class DemoTest {
@Test
public void test1(){
StringBuilder sb = new StringBuilder();
//拼接数字
for (int i = 0; i < 10; i++) {
sb.append(i).append(",");
}
//去掉最后一个逗号
//使用字符串截取
String str = sb.toString();
String substring = str.substring(0, str.length() - 1);
System.out.println(substring);
}
}
- 在代码中去掉
public class DemoTest {
@Test
public void test1(){
StringBuilder sb = new StringBuilder();
//拼接数字
for (int i = 0; i < 10; i++) {
sb.append(i);
//判断
if (i!=9) {
sb.append(",");
}
}
System.out.println(sb);
}
}
- 笔试题:把字符串逆序输出?
public class DemoTest {
@Test
public void test1(){
String str = "hadoop";
StringBuilder sb = new StringBuilder(str);
//调用方法
StringBuilder reverse = sb.reverse();
System.out.println(reverse);
}
}
7.4 基本类型对应的包装类型
7.4.1 包装类型提供了更多的实用方法
- 类型转换
- 包装类型都是final修饰的
- 都是不可变对象
基本类型 | 包装类型 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
char | Character |
boolean | Boolean |
7.4.2 类层次结构

7.4.2.1 类型转换的方法
- 除Boolean和Character以外,其它包装类都有转为包装类型和基本类型的方法
public class DemoTest {
@Test
public void test1(){
String str = "100";
//转为包装类型
Integer integer = Integer.valueOf(str);
//转为基本类型
int i = Integer.parseInt(str);
}
}
7.4.2.2 自动拆装箱
- 自动将基本类型转为对象--装箱
- 自动将对象转为基本类型--拆箱
- 笔试题
public class DemoTest {
@Test
public void test1(){
//取值的范围是按照byte的范围获取的
Integer i = 128;
Integer n = 128;
//返回false
System.out.println(i == n);
}
}
7.5 日期类
7.5.1 传统方式
import org.junit.Test;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DemoTest {
@Test
public void test1(){
//传统的日期类已经不建议使用,因为,效率低
Date date = new Date();
System.out.println(date);
//设置日期格式:HH表示24小时制;hh表示12小时制
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(sdf.format(date));
}
}
7.5.2 使用新的日期类
import org.junit.Test;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
public class DemoTest {
@Test
public void test1(){
//获取日期
LocalDate date = LocalDate.now();
System.out.println(date);
//获取时间
LocalTime time = LocalTime.now();
System.out.println(time);
}
@Test
public void test2(){
//获取日期时间
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime);
}
@Test
public void test3(){
//获取日期时间:使用标准格式化
DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
LocalDateTime dateTime = LocalDateTime.now();
//格式化
System.out.println(formatter.format(dateTime));
}
@Test
public void test4(){
//获取日期时间:使用自定义格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.now();
//格式化
System.out.println(formatter.format(dateTime));
}
}
7.5.3 添加时间
import org.junit.Test;
import java.time.LocalDateTime;
public class DemoTest {
@Test
public void test1(){
//指定日期时间
LocalDateTime dateTime = LocalDateTime.of(2022, 02, 11, 12, 25);
System.out.println(dateTime);
}
@Test
public void test2(){
//添加年、月、日...
LocalDateTime dateTime = LocalDateTime.now();
LocalDateTime plusDays = dateTime.plusDays();
System.out.println(plusDays);
}
}

7.5.4 减少时间
import org.junit.Test;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class DemoTest {
@Test
public void test1(){
//减少年、月、日...
LocalDateTime dateTime = LocalDateTime.now();
LocalDateTime minusDays = dateTime.minusDays(3);
System.out.println(DateTimeFormatter.ofPattern("yyyy-MM-DD HH:mm:ss").format(minusDays));
}
}

7.5.5 其它的日期方法
import org.junit.Test;
import java.time.*;
import java.time.temporal.TemporalAdjusters;
import java.util.Set;
public class DemoTest {
@Test
public void test1(){
//获取日期
LocalDateTime dateTime = LocalDateTime.now();
System.out.println(dateTime.getYear());
System.out.println(dateTime.getMonthValue());
System.out.println(dateTime.getHour());
System.out.println(dateTime.getDayOfWeek());
System.out.println(dateTime.getDayOfYear());
}
@Test
public void test2(){
//时间戳
System.out.println("长整型时间戳:"+System.currentTimeMillis());
}
@Test
public void test3(){
//时间戳
Instant instant = Instant.now();
//我们的时区和标准默认的时区相差8小时
System.out.println("默认的时区"+instant);
//必须添加上相差的8小时
OffsetDateTime offsetDateTime = instant.atOffset(ZoneOffset.ofHours(8));
System.out.println("我们的时区时间"+offsetDateTime);
//获取时间戳
System.out.println("获取时间戳"+offsetDateTime.toEpochSecond());
}
@Test
public void test4(){
LocalDateTime dateTime1 = LocalDateTime.of(2021, 12, 25, 14, 25);
LocalDateTime dateTime2 = LocalDateTime.of(2021, 12, 28, 14, 25);
//差
Duration duration = Duration.between(dateTime1, dateTime2);
System.out.println("天数:"+duration.toDays());
System.out.println("秒数:"+duration.getSeconds());
}
@Test
public void test5(){
//计算日期差
LocalDate date1 = LocalDate.of(2022, 02, 11);
LocalDate date2 = LocalDate.of(2022, 03, 11);
//差
Period between = Period.between(date1, date2);
System.out.println("天数:"+between.getDays());
System.out.println("月数:"+between.getMonths());
}
@Test
public void test6(){
//时间校正器
LocalDateTime dateTime = LocalDateTime.now();
//获取下一天
LocalDateTime with = dateTime.with(TemporalAdjusters.lastDayOfMonth());
System.out.println(with);
}
@Test
public void test7(){
//查看时区
Set<String> set = ZoneId.getAvailableZoneIds();
set.forEach(System.out::println);
}
@Test
public void test8(){
//指定时区
LocalDateTime now = LocalDateTime.now();
ZonedDateTime az = now.atZone(ZoneId.of("Asia/Shanghai"));
System.out.println(az);
//可以看到有8小时的差值:2022-03-22T18:32:05.812+08:00[Asia/Shanghai]
}
}
7.6 数字类
7.6.1 货币类型DecimalFormat
- 案例:千进位符
import java.text.DecimalFormat;
public class Demo {
public static void main(String[] args) {
//货币格式
DecimalFormat decimalFormat = new DecimalFormat("###,###.##");
String format = decimalFormat.format(123456.123456);
System.out.println(format);
}
}
- 案例:规定小数的位数
import java.text.DecimalFormat;
public class Demo {
public static void main(String[] args) {
//货币格式
DecimalFormat decimalFormat = new DecimalFormat("###,###.0000");
String format = decimalFormat.format(123456.127);
System.out.println(format);
}
}
7.6.2 使用财务数据BigDecimal
- 可以使用财务数据的专用方法
import java.math.BigDecimal;
public class Demo {
public static void main(String[] args) {
//财务数据
BigDecimal v1 = new BigDecimal(20);
BigDecimal v2 = new BigDecimal(30);
//相加
BigDecimal add = v1.add(v2);
System.out.println(add);
}
}
7.7 Random随机数
7.7.1 随机数的范围0-1
public class Demo {
public static void main(String[] args) {
double random = Math.random();
System.out.println(random);
}
}
7.7.2 工具包下的随机数
import java.util.Random;
public class Demo {
public static void main(String[] args) {
Random random = new Random();
//可以指定随机数的范围
for (int i = 0; i < 10; i++) {
int n = random.nextInt(10);
System.out.println(n);
}
}
}
7.8 Enum枚举类型
- 枚举就是为了定义标准,枚举中的参数都是常量。
7.8.1 案例
public class Demo {
public static void main(String[] args) {
int i = 10;
if (i>=10){
System.out.println(Msg.SUCCESS);
}else{
System.out.println(Msg.FILAURE);
}
}
}
//创建枚举类
enum Msg{
SUCCESS,FILAURE;
}
7.8.2 枚举的真实应用场景
- 创建枚举类
//枚举类
public enum Msg {
DEL("删除",1),SHOW("显示",0);
private String message;
private Integer flag;
//含参数的构造方法
private Msg(String message,int flag){
this.message = message;
this.flag = flag;
}
public String getMessage() {
return message;
}
public Integer getFlag() {
return flag;
}
}
- 使用
public class Demo {
public static void main(String[] args) {
//获取标识及对应的数字
String message = Msg.DEL.getMessage();
Integer flag = Msg.DEL.getFlag();
//显示
System.out.println(message);
System.out.println(flag);
}
}
7.9 实体类:JavaBean
- 注意:实体类的属性必须是包装类型,因为,我们只需要判断null或者非null即可
public class Person {
private String username;
private String sex;
private Integer age;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}