JavaSE-第七章

发布于 2022-04-07  114 次阅读


第七章 常用类

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修饰的
  • 都是不可变对象
基本类型包装类型
byteByte
shortShort
intInteger
longLong
floatFloat
doubleDouble
charCharacter
booleanBoolean

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;
    }
}


我从未觉得繁琐,说浪漫些,我很爱你。