[豪の学习笔记] JavaReStudy#11

跟学视频:韩顺平Java课程

常用类

1 - 包装类Wrapper

针对八种基本数据类型相应的引用类型——包装类

有了类的特点就可以调用类的方法

包装类和基本数据的转换

jdk5前的手动装箱和拆箱方式

// 手动装箱 int->Integer
int n1 = 100;
Integer inte = new Integer(n1);
Integer inte2 = Integer.valueOf(n1);
// 手动拆箱 Integer->int
int i = inte.intValue();

jdk5以后(含jdk5)的自动装箱和拆箱方式

// 自动装箱
int n2 = 200;
Integer integer = n2; // 底层使用的是Integer.valueOf(n2)
int n3 = integer; // 底层仍然使用的是 intValue()方法

包装类方法

// Integer --> String
Integer i = 100;
String str1 = i + "";
String str2 = i.toString();
String str3 = String.valueOf(i);
//  String --> Integer
String str4 = "12345";
Integer i2 = Integer.parseInt(str4);
Integer i3 = new Integer(str4);

Integer.MIN_VALUE 返回最小值
Integer.MAX_VALUE 返回最大值
Character.isDigit('6') 判断是不是数字
Character.isLetter('a') 判断是不是字母
Character.isUpperCase('a') 判断是不是大写
Character.isLowerCase('a') 判断是不是小写
Character.isWhitespace('a') 判断是不是空格
Character.toUpperCase('a') 转成大写
Character.toLowerCase('A') 转成小写

2 - String类

基本介绍

String对象用于保存字符串,也就是一组字符序列

字符串常量对象使用双引号括起的字符序列

字符串的字符使用Unicode字符编码,一个字符占两个字节

String类较常用的构造器:

①String s1 = new String();

②String s2 = new String(String original);

③String s3 = new String(char[] a);

④String s4 = new String(char[] a, int startIndex, int count);

String类实现了接口Serializable,使得String可以串行化(可在网络传输)

String类实现了接口Comparable,使得String对象可以比较大小

String是final类,不能被其他的类继承

String有属性private final char value[];    用于存放字符串内容

JDK9后String类的实现底层由char[]改为byte[]

创建方式

方式一:直接赋值    String str = "MagicShushu";

先从常量池查看是否有"MagicShushu"数据空间,如果有则直接指向;如果没有则创建并指向。str最终指向的是常量池的空间地址

方式二:调用构造器    String str2 = new String("MagicShushu");

先在堆中创建空间,里面维护了value属性,指向常量池的MagicShushu空间,如果常量池没有"MagicShushu",重新创建,如果有则直接通过value指向。str2最终指向的是堆中的空间地址

String a = "shushu"; //a指向常量池的"shushu"
String b = new String("shushu"); //b指向堆中对象
System.out.println(a.equals(b)); //T
System.out.println(a == b); //F
System.out.println(a == b.intern()); //T
System.out.println(b == b.intern()); //F
// 当调用intern方法时,如果池已经包含一个等于此String对象的字符串(用equals(Object)方法确定),则返回池中的字符串,否则将此String对象添加到池中,并返回String对象的引用
// b.intern()方法最终返回的是常量池的地址

Person p1 = new Person();
p1.name = "shushu";
Person p2 = new Person();
p2.name = "shushu";

System.out.println(p1.name.equals(p2.name)); //T
System.out.println(p1.name == p2.name); //T
System.out.println(p1.name == "hspedu"); //T

String s1 = new String("bcde");
String s2 = new String("bcde");
System.out.println(s1==s2); //F

3 - 字符串的特性

String是一个final类,代表不可变的字符序列

字符串是不可变的,一个字符串对象一旦被分配,其内容是不可变的

String a = "hello" + "abc";
创建了几个对象?只有一个对象
编译器不傻,自动做了优化,判断创建的常量池对象是否有引用指向
String a = "hello" + "abc"; --> String a = "helloabc";

String a = "hello";
String b = "abc";
String c = a + b;
底层是:
StringBuilder sb = new StringBuilder();
sb.append(a);
sb.append(b);
String c1 = "ab" + "cd"; 常量相加,看的是池
String c2 = a + b; 变量相加,是在堆中

4 - String类的常见方法

String类是保存字符串常量的,每次更新都需要重新开辟空间,效率较低,因此Java设计者还提供了StringBuilder和StringBuffer来增强String的功能并提高效率

equals() //区分大小写,判断内容是否相等
equalsIgnoreCase() //忽略大小写的判断内容是否相等
length() //获取字符的个数,字符串的长度
indexOf() //获取字符在字符串中第一次出现的索引,索引从0开始,如果找不到则返回-1
lastIndexOf() //获取字符在字符串中最后一次出现的索引,索引从0开始,如找不到则返回-1
substring() //截取指定范围的字串
trim() //去除前后空格
charAt() //获取某索引处的字符

toUpperCase() //转换成大写
toLowerCase() //转换成小写
concat() //拼接字符串
replace() //替换字符串中的字符
split() //分割字符串,某些分割字符需要转义
toCharArray() //转换成字符数组
compareTo() //比较两个字符串的大小,如果前者大则返回正数,后者大则返回负数,相等返回0

5 - StringBuffer类

基本介绍

java.lang.StringBuffer代表可变的字符序列,可以对字符串内容进行增删,很多方法与String相同,但StringBuffer是可变长度的

StringBuffer是一个容器

StringBuffer实现了Serializable,即StringBuffer的对象可以串行化

StringBuffer 是一个 final 类,不能被继承

StringBuffer的直接父类是AbstractStringBuilder,在父类中AbstractStringBuilder有属性char[] value,不是 final

因为StringBuffer字符内容是存在char[] value,,所以在变化(增加/删除)不用每次都更换地址(即不是每次创建新对象), 故效率高于String

String与StringBuffer

String保存的是字符串常量,里面的值不能更改,每次String类的更新实际上就是更改地址,效率较低

StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新实际上可以更新内容,不用每次更新地址,效率较高

String和StringBuffer相互转换

①String --> StringBuffer

String str = "hello";
//方式一 使用构造器,返回的是StringBuffer对象,对str本身没有影响
StringBuffer stringBuffer = new StringBuffer(str);
//方式二 使用append方法
StringBuffer stringBuffer1 = new StringBuffer();
stringBuffer1 = stringBuffer1.append(str);

②StringBuffer --> String

StringBuffer stringBuffer3 = new StringBuffer("shushu");
//方式一 使用StringBuffer提供的toString方法
String s = stringBuffer3.toString();
//方式二 使用构造器来搞定
String s1 = new String(stringBuffer3);

StringBuffer类常见方法

StringBuffer s = new StringBuffer("hello");
// 增加
s.append(',');    //"hello,"
s.append("shushu");    //"hello,shushu"
s.append("baka").append(666).append(true).append(11.11);    //"hello,shushubaka666true11.11"
// 删除索引为>=start && <end 处的字符
s.delete(11, 14);
System.out.println(s);    //"hello,shushka666true11.11"
// 替换索引x~y的字符[x,y)
s.replace(9, 11, "Magic");
System.out.println(s);    //"hello,shuMagicka666true11.11"
// 查找指定的子串在字符串第一次出现的索引,如果找不到返回-1
int indexOf = s.indexOf("shu");
System.out.println(indexOf);    //6
// 索引为9的位置插入"XXX",原来索引为9的内容自动后移
s.insert(9, "XXX");
System.out.println(s);    //"hello,shuXXXMagicka666true11.11"
// 长度
System.out.println(s.length()); //30

6 - StringBuilder类

基本介绍

一个可变的字符序列,此类提供一个与StringBuffer兼容的API,但不保证同步(StringBuilder不是线程安全),该类被设计用作StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候。如果可能,建议优先采用StringBuilder,因为在大多数实现中,StringBuilder比StringBuffer快

StringBuilder上的主要操作是append和insert方法,可重载这些方法以接收任意类型的数据

StringBuilder和StringBuffer均代表可变的字符序列,方法是一样的

StringBuilder继承AbstractStringBuilder类

StringBuilder实现了接口Serializable,说明StringBuilder对象是可以串行化(对象可以网络传输,可以保存到文件)

StringBuilder是final类, 不能被继承

StringBuilder对象字符序列仍然是存放在其父类AbstractStringBuilder的char[] value

StringBuilder的方法没有做互斥的处理,即没有 synchronized 关键字,因此在单线程的情况下使用

String、StringBuffer和StringBuilder的比较

StringBuilder和StringBuffer非常类似,均代表可变的字符序列,而且方法也一样

String:不可变字符序列,效率低但是复用率高

StringBuffer:可变字符序列,效率较高,线程安全

StringBuilder:可变字符序列,效率最高,线程不安全

7 - Math类

Math类包含用于执行基本数学运算的方法,如初等指数、对数、平方根、三角函数等

abs(x) //返回x的绝对值
pow(x,y) //求x的y次幂
ceil(x) //向上取整,返回>=x的最小整数(转换成double)
floor(x) //向下取整,返回<=x的最大整数(转换成double)
round(x) //四舍五入x
sqrt(x) //对x开方
random() //返回的是0<=x<1之间的一个随机小数

acos() //返回一个值的反余弦,返回的角度范围在0~pi之间
asin() //返回一个值的反正弦,返回的角度范围在-pi/2~pi/2之间
atan() //返回一个值的反正切,返回的角度范围在-pi/2~pi/2之间
atan2() //将矩阵坐标(x,y)转换成极坐标(r,theta),返回所得角theta
cbrt() //返回立方根

8 - Arrays类

Arrays里面包含了一系列的静态方法,用于管理或操作数组(如排序和搜索)

toString

返回数组的字符串形式

sort

自然排序或定制排序

因为数组是引用类型,所以通过sort排序后,会直接影响到实参arr

可以通过传入一个接口 Comparator 实现定制排序

Arrays.sort(arr); // 默认排序方法
//定制排序
Arrays.sort(arr, new Comparator(){
    @Override
    public int compare(Object o1, Object o2) {
    Integer i1 = (Integer) o1;
    Integer i2 = (Integer) o2;
    return i2 - i1;
    }
});
public static void bubblee2(int[] arr, Comparator c){
    int temp =0;
    for (int i = 0; i < arr.length - 1; i++){
        for(int j = 0; j < arr.length - 1 - i; j++){
            if(c.compare(arr[j],arr[j+1])>0){
                temp = arr[j];
                arr[j]=arr[j+1];
                arr[j+1]=temp;
            }
        }
    }
}

binarySearch

通过二分搜索法进行查找,要求必须先排好序

copyOf

数组元素的复制

从arr数组中,拷贝arr.length个元素到newArr数组中

如果拷贝的长度 > arr.length就在新数组的后面增加null,如果拷贝长度 < 0 就抛出异常 NegativeArraySizeException

该方法的底层使用的是 System.arraycopy()

fill

数组元素的填充

equals

比较两个数组元素内容是否完全一致

asList

将一组值转换成list

定制排序练习

import java.util.Arrays;
import java.util.Comparator;

public class Main {
    public static void main(String[] args) {
        Book[] books = new Book[4];
        books[0] = new Book("红楼梦",100);
        books[1] = new Book("金瓶花新",96);
        books[2] = new Book("青年文摘2e年",5);
        books[3] = new Book("java从入门到放弃~",300);

        //(1)price从大到小排序
//        Arrays.sort(books, new Comparator(){
//            @Override
//            public int compare(Object o1, Object o2) {
//                Book b1 = (Book) o1;
//                Book b2 = (Book) o2;
//                double priceVal = b2.getPrice() - b1.getPrice();
//                if (priceVal > 0) {
//                    return 1;
//                }else if (priceVal < 0) {
//                    return -1;
//                }else{
//                    return 0;
//                }
//            }
//        });

        //(2)price从小到大排序
//        Arrays.sort(books, new Comparator(){
//            @Override
//            public int compare(Object o1, Object o2) {
//                Book b1 = (Book) o1;
//                Book b2 = (Book) o2;
//                double priceVal = b2.getPrice() - b1.getPrice();
//                if (priceVal > 0) {
//                    return -1;
//                }else if (priceVal < 0) {
//                    return 1;
//                }else{
//                    return 0;
//                }
//            }
//        });

        //(3)根据书名长度排序
        Arrays.sort(books, new Comparator(){
            @Override
            public int compare(Object o1, Object o2) {
                Book b1 = (Book) o1;
                Book b2 = (Book) o2;
                return b1.getName().length() - b2.getName().length();
            }
        });

        System.out.println(Arrays.toString(books));
    }
}

class Book{
    private String name;
    private double price;

    public Book(String name, double price){
        this.name = name;
        this.price = price;
    }

    public double getPrice() {
        return price;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return "Book{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

9 - System类

exit()

退出当前程序

System.exit(0)表示以正常状态退出

arraycopy()

复制数组元素,比较适合底层调用,一般使用Arrays.copyOf()完成复制数组

currentTimeMillens()

返回当前时间距离1970-01-01的毫秒数

gc()

运行垃圾回收机制 System.gc()

10 - BigInteger和BigDecimal

BigInteger适合保存比较大的整型

BigDecimal适合保存精度更高的浮点型

常见方法

add 加

subtract 减

multiply 乘

divide 除

11 - 第一代日期类

Date 精确到毫秒,代表特定的瞬间

SimpleDateFormat 格式和解析日期的具体类,它允许进行格式化(日期--->文本),解析(文本--->日期)和规范化

Date day1 = new Date(); //获取当前系统时间
Date day2 = new Date(1145149981); //通过指定毫秒数得到时间
System.out.println(day1.getTime()); //获取某个时间对应的毫秒数
//这里的Date类是在java.util包,默认输出的日期格式是国外的方式,因此通常需要对格式进行转换

SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E"); //创建SimpleDateFormat对象,可以指定相应的格式,格式使用的字母是规定好的,不能乱写
String format = sdf.format(day1); //format:将日期转换成指定格式的字符串

//可以把一个格式化的String转成对应的Date,得到的Date在输出时仍然是国外的形式,如果希望指定格式输出则需要转换
String s = "2005年01月01日 12:22:23 星期六";
Date parse = sdf.parse(s); //此处可能存在异常,需要抛出

12 - 第二代日期类

主要是Calendar类(日历)

public abstract class Calendar extends Object implements Serializable,Cloneable,Comparable

Calendar类是一个抽象类,并且构造器是private,它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR等日历字段之间的转换提供了一些方法,并为操作日历字段(如获得下星期的日期)提供了一些方法

可以通过getInstance()来获取实例

Calendar没有提供对应的格式化的类,因此需要程序员自己组合来输出

如果我们需要按照24小时进制来获取时间,Calendar.HOUR 改成 Calendar.HOUR_OF_DAY

Calendar c = Calendar.getInstance(); //创建日历类对象
System.out.println("年:" + c.get(Calendar.YEAR)); //获取日历对象的某个日历字段
System.out.println("月:" + (c.get(Calendar.MONTH) + 1)); //Calendar返回月时候是按照0开始编号
System.out.println("日:" + c.get(Calendar.DAY_OF_MONTH));
System.out.println("小时:" + c.get(Calendar.HOUR));
System.out.println("分钟:" + c.get(Calendar.MINUTE));
System.out.println("秒:" + c.get(Calendar.SECOND));
System.out.println(c.get(Calendar.YEAR) + "-" + (c.get(Calendar.MONTH) + 1) + "-" + c.get(Calendar.DAY_OF_MONTH) + " " + c.get(Calendar.HOUR) + ":" + c.get(Calendar.MINUTE) + ":" + c.get(Calendar.SECOND));

13 - 第三代日期类

前两代日期类不足分析

JDK1.0中包含了一个java.util.Date类,但是它的大多数方法已经在JDK1.1引入Calendar类之后被弃用了,而Calendar也存在的问题是:

①可变性:像日期和时间这样的类应该是不可变的

②偏移性:Date中的年份是从1900年开始的,而月份都是从0开始

③格式化:格式化只对Date有用Calendar则不行

④此外,它们也不是线程安全的,也不能处理闰秒(每隔两天多出1s)等问题

基本介绍

LocalDate(日期/年月日)、LocalTime(时间/时分秒)、LocalDateTime(日期时间/年月日时分秒)在JDK8加入

LocalDate只包含日期,可以获取日期字段    LocalTime只包含时间,可以获取时间字段    LocalDateTime包含日期 + 时间,可以获取日期和时间字段

//使用now()返回表示当前日期时间的对象
LocalDateTime ldt = LocalDateTime.now(); //LocalDate.now();//LocalTime.now()
System.out.println(ldt);
//创建DateTimeFormatter对象,使用DateTimeFormatter对象来进行格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String format = dateTimeFormatter.format(ldt);
System.out.println("格式化的日期=" + format);
System.out.println("年=" + ldt.getYear());
System.out.println("月=" + ldt.getMonth());
System.out.println("月=" + ldt.getMonthValue());
System.out.println("日=" + ldt.getDayOfMonth());
System.out.println("时=" + ldt.getHour());
System.out.println("分=" + ldt.getMinute());
System.out.println("秒=" + ldt.getSecond());
LocalDate now = LocalDate.now(); //可以获取年月日
LocalTime now2 = LocalTime.now();//获取到时分秒

DateTimeFormatter格式日期类

类似于SimpleDateFormat

DateTimeFormat dtf = DateTimeFormatter.ofPattern(格式);
String str = dtf.format(日期对象);

LocalDateTime ldt = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH小
时mm分钟ss秒");
String strDate = dtf.format(ldt);

Instant时间戳

类似于Date,提供了一系列和Date类转换的方式

//Instant --> Date
Date date = Date.from(instant);
//Date ---> Instant
Instant instant = Instant.now();

//通过静态方法now()获取表示当前时间戳的对象
Instant now = Instant.now();
System.out.println(now);
//通过from可以把Instant转成Date
Date date = Date.from(now);
//通过date的toInstant()可以把date转成Instant对象
Instant instant = date.toInstant();

第三代日期类更多方法

LocalDateTime类
MonthDay类:检查重复事件
是否是闰年
增加日期的某个部分
使用plus方法测试增加时间的某个部分
使用minus方法测试查看一年前和一年后的日期
其他的方法自己查看API使用即可

posted @ 2025-03-30 21:31  SchwarzShu  阅读(21)  评论(0)    收藏  举报