java常用类

目录

包装类

 包装类和基本数据类型的转换(装箱和拆箱)

 包装类练习

经典面试题⭐

包装类型和String类型的相互转换

Integer类和Character类的常用方法

Integer类面试题

String类

两种创建String对象的区别

 String小练习

字符串的特性

String的常见方法

StriingBuffer类

 String VS StringBuffer

 StringBuffer构造器

StringBuffer与String相互转换

StringBuffer常用方法 

 StringBuffer练习

StringBuilder类

String、StringBuilder、StringBuffer的比较(面试常问)

Math类

Arrays类

sort()

binarySearch()

 copyOf()

fill()

asList()

Arrays类练习

System类

 exit()

arraycopy()

currentTimeMillis()

BigInteger类和BigDecimal类

Date类

SimpleDateFormat日期格式类

Calendar类(日历)

第三代日期类 

DateTimeFormatter格式日期类 

 plus和minus方法

Instant时间戳

练习题


包装类

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


 包装类和基本数据类型的转换(装箱和拆箱)

  1. jdk5以前的手动装箱和拆箱方式,装箱:基本类型->包装类型,拆箱反之
  2. jdk5以后的自动装箱和拆箱方式
  3. 自动装箱底层调用的是valueOf方法,比如Integer.valueOf()
package com.lili.wrapper;

public class Integer01 {
    public static void main(String[] args) {
        //int的装箱和拆箱
        //jdk5前手动装箱和拆箱
        //手动装箱int -> Integer
        int n1 = 100;
        Integer integer = new Integer(n1);
        //或Integer integer1 = Integer.valueOf(n1);

        //手动拆箱Integer -> int
        int i = integer.intValue();

        //jdk5后自动装箱和拆箱
        int n2 = 200;
        //自动装箱 int -> Integer
        Integer integer2 = n2;  //底层使用的是Integer.valueOf(n2)

        //自动拆箱 Integer -> int
        int n3 = integer2;
    }
}

 包装类练习

下面代码正确吗?

Double d = 100d; //①
Float f = 1.5f;  //②

 answer:

都正确

①自动装箱,底层:Double.valueOf(100d)

②自动装箱,底层:Float.valueOf(1.5f)


经典面试题⭐

以下两个输出一样吗?

haohaosikao~

//1
Object obj1 = true ? new Integer(1) : new Double(2.0);
System.out.println(obj1);
//2
Object obj2;
if(true) {
    obj2 = new Integer(1);
}else {
    obj2 = new Double(2.0);
}
    System.out.println(obj2);

answer:

不一样

三元运算符是一个整体,int型的1会自动转换类型为最高精度double,变为1.0

所以输出结果是:

1.0


包装类型和String类型的相互转换

以Integer为例: 

public class WrapperVSString {
    public static void main(String[] args) {
        Integer i = 100; //自动装箱
        //包装类(Integer) -> String
        //方式1
        String str1 = i + "";
        //方式2
        String str2 = i.toString();
        //方式3
        String str3 = String.valueOf(i);

        //String -> 包装类(Integer)
        String str4 = "123";
        //方式1
        Integer integer = Integer.parseInt(str4);
        //方式2
        Integer integer1 = new Integer(str4);
    }
}

Integer类和Character类的常用方法

Integer->右键Diagrams->Show Diagram可以看到Integer包装类的结构图 

点击红色小圆圈m可以看到Integer的所有方法 

package com.lili.wrapper;

public class WrapperMethod {
    public static void main(String[] args) {
        System.out.println(Integer.MAX_VALUE);
        System.out.println(Integer.MIN_VALUE);

        System.out.println(Character.isDigit('a')); //判断是不是数字
        System.out.println(Character.isLetter('a')); //判断是不是字母
        System.out.println(Character.isUpperCase('a')); //判断是不是大写
        System.out.println(Character.isLowerCase('a')); //判断是不是小写

        System.out.println(Character.isWhitespace('a')); //判断是不是空格
        System.out.println(Character.toUpperCase('a'));  //转成大写
        System.out.println(Character.toLowerCase('A'));  //转成小写
    }
}

Integer类面试题

1.看看下段代码会输出什么? (有点难度)⭐

public class WrapperExercise02 {
    public static void main(String[] args) {
        Integer integer = new Integer(1);
        Integer integer1 = new Integer(1);
        System.out.println(integer == integer1);  //①

        Integer m = 1;
        Integer n = 1;
        System.out.println(m == n);   //②

        Integer x = 128;
        Integer y = 128;
        System.out.println(x == y);   //③
    }
}

answer:

本题需要了解Integer的底层原理(查看源码)

 alt + 7查看Integer的结构

或者点击左下角图标查看Integer的结构

Integer的valueOf()方法源码: 

对于①,很简单,2个Integer对象都是new创建的,指向不同的地址,所以integer != integer1,输出false;

对于②,自动装箱,底层用的是Integer.valueOf(1),1在IntegerCache.low~IntegerCache.high(-128~127)之间,所以直接返回的是1,输出true;

对于②,自动装箱,底层Integer.valueOf(128),128不在IntegerCache.low~IntegerCache.high,

所以返回的是new Integer(128),输出false.


2.  5min思考以下代码输出什么?

package com.lili.wrapper;

public class WrapperExercise03 {
    public static void main(String[] args) {
        Integer i1 = new Integer(127);
        Integer i2 = new Integer(127);
        System.out.println(i1 == i2); //1

        Integer i3 = new Integer(128);
        Integer i4 = new Integer(128);
        System.out.println(i3 == i4); //2

        Integer i5 = 127;
        Integer i6 = 127;
        System.out.println(i5 == i6); //3

        Integer i7 = 128;
        Integer i8 = 128;
        System.out.println(i7 == i8); //4

        Integer i9 = 127;
        Integer i10 = new Integer(127);
        System.out.println(i9 == i10); //5

        Integer i11 = 127;
        int i12 = 127;
        System.out.println(i11 == i12); //6

        Integer i13 = 128;
        int i14 = 128;
        System.out.println(i13 == i14); //7
    }
}

answer:

 对于7和8,只要有基本数据类型,判断的就是值是否相等⭐

package com.lili.wrapper;

public class WrapperExercise03 {
    public static void main(String[] args) {
        System.out.print("1 ");
        Integer i1 = new Integer(127);
        Integer i2 = new Integer(127);
        System.out.println(i1 == i2); //1 false

        System.out.print("2 ");
        Integer i3 = new Integer(128);
        Integer i4 = new Integer(128);
        System.out.println(i3 == i4); //2 false

        System.out.print("3 ");
        Integer i5 = 127;
        Integer i6 = 127; //底层Integer.valueOf(127),127∈[-128,127],返回127
        System.out.println(i5 == i6); //3 true

        System.out.print("4 ");
        Integer i7 = 128;
        Integer i8 = 128; //底层Integer.valueOf(128),128不在[-128,127],返回new Integer(128)
        System.out.println(i7 == i8); //4 false

        System.out.print("5 ");
        Integer i9 = 127; //Integer.valueOf(127)返回127
        Integer i10 = new Integer(127);
        System.out.println(i9 == i10); //5 false

        System.out.print("6 ");
        Integer i11 = 127;
        int i12 = 127;  //只要有基本数据类型,判断的就是值是否相等
        System.out.println(i11 == i12); //6 true

        System.out.print("7 ");
        Integer i13 = 128;
        int i14 = 128;
        System.out.println(i13 == i14); //7 true
    }
}

String类

  •  String对象用于保存字符串,即一组字符序列
  • 字符串常量是用双引号“”包起的字符序列
  • 字符串的字符使用Unicode编码,一个字符统一占2个字节
  • String类是final类,不能被继承
  • String类实现了 Serializable接口,String可以串行化(可以网络传输);String类实现了Comparable接口,String对象可以比较大小

  • String类有很多构造器

 String类有属性private final char value[],用于存放字符串内容,注意:value[]是final,不可以修改,这里的不能修改指的是value不能指向新的地址,而不是值不能修改!⭐⭐


两种创建String对象的区别

1. 直接赋值 String name = "kiddy";

先从常量池查看是否有"kiddy"空间,如果有,直接指向;如果没有则创建一个,再指向,name最终指向的是常量池的空间地址。

2. 调用构造器 String name2 = new String("kiki");

先在堆中创建空间,name2指向堆中创建的这个空间。堆中维护一个char[]类型的value属性,value指向常量池的一块空间,查看常量池是否有"kiki"空间,如果有,value直接指向;如果没有则创建一个,value指向。name2最终指向的是堆中的空间地址。


 String小练习

1. 看看下面的代码会输出什么? 

package com.lili.String_;

public class StringExercise01 {
    public static void main(String[] args) {
        String s1 = "abc";
        String s2 = "abc";
        System.out.println(s1.equals(s2));
        System.out.println(s1 == s2);
    }
}

answer:

true

true

字符串的equals方法判断的是值是否相等,

字符串1 == 字符串2 判断的是是否是一个对象。

s1 与 s2 都指向常量池的 "abc",是一个对象 

再看一个:


2. 本题需要了解一下字符串的intern方法 

intern():如果字符串常量池存在和当前字符串对象值相同的字符串对象(equals==true),那么返回字符串常量池里那个对象,如果不存在,把当前字符串对象存进常量池,,返回当前字符串对象,即最终返回的还是常量池中的对象

来看看下面这道题吧~

package com.lili.String_;

public class StringExercise03 {
    public static void main(String[] args) {
        String a = "haha";
        String b = new String("haha");
        System.out.println(a.equals(b));
        System.out.println(a == b);
        System.out.println(a == b.intern());
        System.out.println(b == b.intern());
    }
}

 answer:

package com.lili.String_;

public class StringExercise03 {
    public static void main(String[] args) {
        String a = "haha";
        String b = new String("haha");
        System.out.println(a.equals(b));  //true
        System.out.println(a == b); //false
        System.out.println(a == b.intern());  //true
        System.out.println(b == b.intern());  //false b指向的是堆中的对象,b.intern()指向的是常量池的对象
    }
}

3. 看输出结果,并画出内存分布草图

package com.lili.String_;

public class StringExercise05 {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.name = "Kidy";
        Person p2 = new Person();
        p2.name = "Kidy";

        System.out.println(p1.name.equals(p2.name));
        System.out.println(p1.name == p2.name);
        System.out.println(p1.name == "Kidy");
    }
}

class Person{
    public String name;
}

answer:

true true true


字符串的特性

1. String 是一个final类,代表不可变的字符序列,字符串对象一旦被分配,内容不可变

 


  2. 再来看一道面试题

String a = "hello" + "abc"; 创建了几个对象?

answer:

创建了一个对象“helloabc”

编译器会进行优化--> String a = "helloabc";


3. 再变动一下看看

String a = "hello";

String b =  "abc";

String c = a + b;

创建了几个对象?

answer:

创建了3个对象


 4.下面代码输出什么?

package com.lili.String_;

public class StringExercise09 {
    public static void main(String[] args) {
        String s1 = "hi";
        String s2 = "kiki";
        String s5 = "hikiki";
        String s6 = (s1 + s2).intern();
        System.out.println(s5 == s6); 
        System.out.println(s5.equals(s6)); 
    }
}

answer: 


 5. 这一题请好好想,思考思考输出什么

有点难度⭐

package com.lili.String_;

public class StringExercise10 {
    public static void main(String[] args) {
        Test t = new Test();
        t.change(t.str, t.ch);
        System.out.print(t.str + " and ");
        System.out.println(t.ch);
    }
}

class Test{
    String str = new String("kiki");
    final char[] ch = {'j', 'a', 'v', 'a'};
    public void change(String str, char[] ch){
        str = "java";
        ch[0] = 'h';
    }
}

answer:


String的常见方法

package com.lili.String_;

public class StringMethod01 {
    public static void main(String[] args) {
        String s1 = "aa & kiki";
        String s2 = s1.replace("aa", "kuku");
        System.out.println(s1); //aa & kiki replace替换的是返回值,s1字符串不变
        System.out.println(s2); //kuku & kiki
    }
}

String格式化输出

String info = String.format("名字是%s,年龄是%d", "kiki", 21);

StriingBuffer类

  1. StringBuffer的直接父类是AbstractStringBuilder
  2. StringBuffer实现了Serializable,StringBuffer对象可以串行化
  3. 父类AbstractStringBuilder中有属性 char[] value,且不是final的,该value数组存放字符串内容,引用存放在堆中
  4. StringBuffer是一个final类,不能被继承

 String VS StringBuffer

String 保存的是字符串常量,里面的值不能修改,每次更新字符串实际是指向一个新的地址,效率较低 private final char[] value

String 保存的是字符串变量,里面的值可以修改,每次更新字符串不用每次更新地址(只要容量不够才更新),效率较高 char[] value(这个放在堆中)


 StringBuffer构造器

package com.lili.StringBuffer_;

public class StringBuffer_ {
    public static void main(String[] args) {
        //1 创建一个大小为16的char[]
        StringBuffer stringBuffer = new StringBuffer();
        //2 通过构造器指定char[]的大小
        StringBuffer stringBuffer1 = new StringBuffer(100);
        //3 通过给一个String对象创建StringBuffer,char[]的大小就是字符串长度+16
        StringBuffer stringBuffer2 = new StringBuffer("hello"); //len:21
    }
}

StringBuffer与String相互转换

String -> StringBuffer:

 1 StringBuffer构造器转换

2 StringBuffer的append方法

StringBuffer -> String:

1 调用StringBuffer的toString方法

2 调用String构造器

package com.lili.StringBuffer_;

public class StringAndStringBuffer {
    public static void main(String[] args) {
        //String -> StringBuffer
        String str = "hello";
        //1 StringBuffer构造器转换
        StringBuffer stringBuffer = new StringBuffer(str);
        //2 StringBuffer的append方法
        StringBuffer stringBuffer1 = new StringBuffer();
        stringBuffer1.append(str);

        //StringBuffer -> String
        StringBuffer stringBuffer2 = new StringBuffer("kiki");
        //1 调用StringBuffer的toString方法
        String str1 = stringBuffer2.toString();
        //2 调用String构造器
        String str2 = new String(stringBuffer2);
    }
}

StringBuffer常用方法 

package com.lili.StringBuffer_;

public class StringBufferMethod {
    public static void main(String[] args) {
        StringBuffer s = new StringBuffer("hello");
        //增
        s.append(',');
        s.append("java");
        s.append(100).append(true).append(8.0);
        System.out.println(s); //hello,java100true8.0

        //删
        //删除[10, 13)的内容
        s.delete(10, 13);
        System.out.println(s); //hello,javatrue8.0

        //改
        //替换[10, 14)的内容
        s.replace(10, 14, "lulu");
        System.out.println(s);

        //查
        //查找字符串第一次出现时的索引位置,找不到返回-1
        int javaIndex = s.indexOf("java");
        System.out.println("javaIndex: " + javaIndex);

        //插
        //在索引为6的位置插入内容,6之后的内容后移
        s.insert(6, "study");
        System.out.println(s);

        //长度
        System.out.println("长度:"+s.length());
    }
}

 StringBuffer练习

1. 看看每条语句是否有问题,看源码,看输出

public class StringBufferExercise01 {
    public static void main(String[] args) {
        String str = null; //ok
        StringBuffer stringBuffer = new StringBuffer(); //ok
        stringBuffer.append(str);  //ok看源码,底层调用的是父类AbstractStringBuilder的appendNull()
        System.out.println(stringBuffer.length()); //输出4

        System.out.println(stringBuffer); //输出null
        StringBuffer stringBuffer1 = new StringBuffer(str); //看源码,不ok,空指针异常
        System.out.println(stringBuffer1); //
    }
}

查看源码知:StringBuffer对象append一个空串,会添加"null"到value[]中 ,所以

stringBuffer.length() = 4;

StringBuffer构造器字符串参数为空时,空对象.length()会有空指针异常


 2. 输入商品名称和商品价格,要求打印效果示例,要求:价格的小数点低位起每3位用逗号隔开

效果示例:

商品名 商品价格

手机    123,5.59 

 主要是解决价格格式化输出问题,将价格用字符串接收,转为StringBuffer类型,就可以用StringBuffer的insert方法插入","

package com.lili.StringBuffer_;

import java.util.Scanner;

public class StringBufferExercise02 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("商品名:");
        String name = scanner.next();
        System.out.print("商品价格:");
        String price = scanner.next();  //价格用字符串接收
        StringBuffer s = new StringBuffer(price); //转为StringBuffer对象
        for (int i = s.indexOf(".") - 3; i > 0; i -= 3) {
            s = s.insert(i, ",");
        }
        System.out.println("商品名\t商品价格\n" + name + "\t" + s);
    }
}

StringBuilder类

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

 

1. StringBuilder继承了AbstractStringBuilder类

2. StringBuilder 实现了Serializable,StringBuilder 对象可以串行化(对象可以网络传输,可以保存到文件)

3. StringBuilder是final类,不能被继承

4. StringBuilder 对象字符序列仍存放在其父类的char[] value 

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


String、StringBuilder、StringBuffer的比较(面试常问)

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

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

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

 如果多次执行改变字符串的操作,会导致大量副本字符串留在内存中,降低效率,

如String s = "a"; s += "b"; 原来的"a"不用了但还在内存中,s指向"ab"。

结论⭐:

  1. 如果字符串存在大量的修改,不要用String,一般用StringBuffer或StringBuilder
  2. 如果字符串存在大量的修改,单线程,使用StringBuilder
  3. 如果字符串存在大量的修改,多线程,使用StringBuilder
  4. 如果字符串很少修改,被多个对象引用,使用String,比如配置信息等

Math类

Math类常用方法(都是静态方法):

package com.lili.math_;

public class MathMethod {
    public static void main(String[] args) {
        //1 abs绝对值
        System.out.println(Math.abs(-1));
        //2 pow求幂
        System.out.println(Math.pow(2, 3));
        //3 ceil向上取整
        System.out.println(Math.ceil(-1.1));
        //4 floor向下取整
        System.out.println(Math.floor(-1.1));
        //5 round四舍五入
        System.out.println(Math.round(7.6));
        //6 sqrt求开方
        System.out.println(Math.sqrt(64));
    }
}

random()返回的是一个[0,1)的随机小数
思考:请写出获取a~b之间的一个随机整数,a,b均为整数,如[2,7] 

int a = 2;
int b = 7;
//(int)(Math.random()*(b-a))得到的是[0,b-a)的整数
//(int)(Math.random()*(b-a+1))得到的是[0,b-a]的整数
for (int i = 0; i < 100; i++) {
    System.out.println(a + (int) (Math.random() * (b - a + 1)));
}

Arrays类

Arrays里面包含了一系列静态方法,用于管理或操作数组

 


sort()

1 默认升序排序
   Arrays.sort(integers);
2 sort重载的也可以通过传入一个接口Comparator实现定制排序,传入2个参数:待排序数组和实现了Comparator接口的匿名内部类,要求实现compare方法 

package com.lili.arrays_;

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

public class ArraysMethod01 {
    public static void main(String[] args) {
        Integer[] integers = {9, -1, 80, 60, 8};
        //Arrays.toString()显示数组
        System.out.println(Arrays.toString(integers));

        //1 默认升序排序
        //Arrays.sort(integers);
        //2 sort重载的也可以通过传入一个接口Comparator实现定制排序
        //  传入2个参数:待排序数组和实现了Comparator接口的匿名内部类,
        //  要求实现compare方法
        Arrays.sort(integers, new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o2 - o1;
            }
        });
        System.out.println("===排序后===");
        System.out.println(Arrays.toString(integers));


    }
}
package com.lili.arrays_;

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

public class ArraysSortCustom {
    public static void main(String[] args) {
        int[] arr = {1, -1, 8, 0, 20};
        //bubble01(arr);
        bubble02(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));
    }

    //冒泡排序
    public static void bubble01(int[] arr){
        int temp = 0;
        for (int i = 0; i < arr.length-1; i++) {
            for (int j = 0; j < arr.length-i-1; j++) {
                if(arr[j] > arr[j+1]){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }

    //冒泡+定制
    public static void bubble02(int[] arr, Comparator c){
        int temp = 0;
        for (int i = 0; i < arr.length-1; i++) {
            for (int j = 0; j < arr.length-i-1; j++) {
                if(c.compare(arr[j],arr[j+1]) > 0){
                    temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                }
            }
        }
    }
}

binarySearch()

通过二分搜索法进行查找,要求数组必须有序

如果数组中不存在该元素,就return -(low + 1);(low是找不到时二分查找算法里的左边界)

package com.lili.arrays_;

import java.util.Arrays;

public class ArraysMethod02 {
    public static void main(String[] args) {
        Integer[] arr = {1, 2, 16, 21, 120, 510};
        //Arrays.binarySearch()通过二分搜索法进行查找,要求必须有序
        int index = Arrays.binarySearch(arr, 1);
        System.out.println(index);
    }
}

 copyOf()

数组元素的复制
1.从原数组中拷贝指定长度元素到新数组中
2.如果拷贝的长度大于原数组长度,就在新数组后面加null
3.如果拷贝的长度小于0,就抛出异常

package com.lili.arrays_;

import java.util.Arrays;

public class ArraysMethod02 {
    public static void main(String[] args) {
        //copyOf() 数组元素的复制
        //1.从原数组中拷贝指定长度元素到新数组中
        //2.如果拷贝的长度大于原数组长度,就在新数组后面加null
        //3.如果拷贝的长度小于0,就抛出异常
        Integer[] newArr = Arrays.copyOf(arr, arr.length);
        System.out.println("===拷贝得到的数组===");
        System.out.println(Arrays.toString(newArr));
    }
}

fill()

数组元素的填充
用指定值替换数组原有的所有元素 

package com.lili.arrays_;

import java.util.Arrays;

public class ArraysMethod02 {
    public static void main(String[] args) {
        //fill()数组元素的填充
        //用指定值替换数组原有的所有元素
        Integer[] num = new Integer[]{9, 2, 3};
        Arrays.fill(num, 88);
        System.out.println("===填充后===");
        System.out.println(Arrays.toString(num));
    }
}

equals()

比较两个数组元素是否完全一致
如果arr1和arr2完全一样,就返回true,否则返回false

package com.lili.arrays_;

import java.util.Arrays;

public class ArraysMethod02 {
    public static void main(String[] args) {
        Integer[] arr1 = {1, 2, 8};
        Integer[] arr2 = {1, 2, 8};
        Integer[] arr3 = {1, 8};
        System.out.println(Arrays.equals(arr1, arr2));
        System.out.println(Arrays.equals(arr1, arr3));
    }
}

asList()

将一组值转换为list
返回的asList的编译类型:List接口
返回的asList的运行类型:java.util.Arrays$ArrayList,是Arrays类的静态内部类

package com.lili.arrays_;

import java.util.Arrays;
import java.util.List;

public class ArraysMethod02 {
    public static void main(String[] args) {
        //asList()
        //将一组值转换为list
        //返回的asList的编译类型:List接口
        //返回的asList的运行类型:java.util.Arrays$ArrayList,是Arrays类的静态内部类
        List asList = Arrays.asList(2,3,4,9,0,6);
        System.out.println("asList = " + asList);
        System.out.println("asList运行类型:" + asList.getClass());
    }
}

Arrays类练习

自定义Book类,包含name和price,分别按price降序排序,按name长度升序排序。要求使用定制排序。

package com.lili.arrays_;

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

public class ArraysExercise {
    public static void main(String[] args) {
        Book[] books = new Book[4];
        books[0] = new Book("红楼梦", 100);
        books[1] = new Book("金瓶梅", 90);
        books[2] = new Book("青年文摘", 5);
        books[3] = new Book("挑战程序设计竞赛", 51);
        //按书的价格降序
        System.out.println("===按书的价格降序===");
        Arrays.sort(books, new Comparator<Book>() {
            @Override
            public int compare(Book o1, Book o2) {
                return o2.getPrice() - o1.getPrice();
            }
        });
        System.out.println(Arrays.toString(books));
//        for (Book book: books){
//            System.out.println(book);
//        }

        //按书名长度升序
        System.out.println("===按书名长度升序===");
        Arrays.sort(books, new Comparator<Book>() {
            @Override
            public int compare(Book o1, Book o2) {
                return o1.getName().length() - o2.getName().length();
            }
        });
        System.out.println(Arrays.toString(books));
    }
}

class Book{
    private String name;
    private int price;

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

    @Override
    public String toString() {
        return name + " " + price;
    }

    public String getName() {
        return name;
    }

    public int getPrice() {
        return price;
    }
}

System类

System类常用方法 


 exit()

exit(0)退出当前程序,

0 表示正常状态

package com.lili.system_;

public class System_ {
    public static void main(String[] args) {
        System.out.println("ok1...");
        System.exit(0);
        System.out.println("ok2...");
    }
}

arraycopy()

拷贝数组

5个参数
@param1      src      源数组
@param2      srcPos   原数组拷贝起始索引
@param3      dest     目标数组
@param4      destPos  目标数组拷贝索引
@param5      length   拷贝长度 

package com.lili.system_;

import java.util.Arrays;

public class System_ {
    public static void main(String[] args) {
        int[] arr = {12, 8, 1};
        int[] destArr = new int[6];
        System.arraycopy(arr, 0, destArr, 1, 2);
        //System.arraycopy(arr, 0, destArr, 0, arr.length);
        System.out.println(Arrays.toString(destArr));
    }
}

currentTimeMillis()

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

package com.lili.system_;

import java.util.Arrays;

public class System_ {
    public static void main(String[] args) {
        //currentTimeMillis()返回当前时间距离1970-1-1的毫秒数
        System.out.println(System.currentTimeMillis());
    }
}

BigInteger类和BigDecimal类

  • BigInteger适合保存比较大的整型;
  • BigDecimal适合保存精度很高的浮点型

1. 在对BigInteger进行加减乘除运算时,需要使用相应的方法,不能直接+-*/ 

package com.lili.bignum;

import java.math.BigInteger;

public class BigInteger_ {
    public static void main(String[] args) {
        BigInteger bigInteger = new BigInteger("1234566666666666666699999");
        System.out.println(bigInteger);
        BigInteger bigInteger1 = new BigInteger("5234526666666666666699999");
        //1 在对BigInteger进行加减乘除运算时,需要使用相应的方法,不能直接+-*/
        System.out.println("+:" + bigInteger.add(bigInteger1));
        System.out.println("-:" + bigInteger1.subtract(bigInteger));
        System.out.println("*:" + bigInteger.multiply(bigInteger1));
        System.out.println("/:" + bigInteger1.divide(bigInteger));
    }
}

 对BigDecimal进行加减乘除运算时,需要使用相应的方法,不能直接+-*/

除运算可能抛出ArithmeticException异常(除不尽)

解决办法:在调用divide()时,指定精度即可

如果有无限循环小数,就会保留分子的精度

package com.lili.bignum;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class BigDecimal_ {
    public static void main(String[] args) {
        BigDecimal bigDecimal = new BigDecimal("3.14159266666666666666888888");
        System.out.println(bigDecimal);
        BigDecimal bigDecimal1 = new BigDecimal("3");
        //对BigDecimal进行加减乘除运算时,需要使用相应的方法,不能直接+-*/
        System.out.println("+:" + bigDecimal.add(bigDecimal));
        System.out.println("-:" + bigDecimal.subtract(bigDecimal1));
        System.out.println("*:" + bigDecimal.multiply(bigDecimal1));
        //除运算可能抛出ArithmeticException异常
        //解决办法:在调用divide()时,指定精度即可
        //如果除不尽(有无限循环小数,就会保留分子的精度)
        //System.out.println("/:" + bigDecimal.divide(bigDecimal1));
        System.out.println("/:" + bigDecimal.divide(bigDecimal1, BigDecimal.ROUND_CEILING));
    }
}

Date类

1. Date()创建的对象:获取当前系统时间 (Date是java.util包下的)

2. Date(long date):通过指定毫秒数得到时间

3. 默认是国外日期输出格式

package com.lili.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Date01 {
    public static void main(String[] args) throws ParseException {
        //1.Date()获取当前系统时间,这里的Date是java.util包下的
        Date date = new Date();
        System.out.println(date);
        //2.Date(long date)通过指定毫秒数得到时间
        Date date1 = new Date(2222240000000l);
        System.out.println(date1);
        //3.默认是国外日期输出格式
    }
}

SimpleDateFormat日期格式类

指定日期输出格式

可以把格式化的字符串转成Date,把String->Date,使用parse()方法;

   字符串格式需和SimpleDateFormat对象一致,否则抛出ParseException异常;

   需在方法声明处throws ParseException

package com.lili.date;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Date01 {
    public static void main(String[] args) throws ParseException {
        Date date = new Date();
        //可以创建SimpleDateFormat对象,指定日期输出格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 hh:mm:ss E");
        System.out.println(sdf.format(date));
        //5.可以把格式化的字符串转成Date
        //  在把String->Date时,使用parse()方法,
        //  字符串格式需和SimpleDateFormat对象一致,否则抛出ParseException异常
        //  需在方法声明处throws ParseException
        String str = "2024年06月30日 09:47:33 星期日";
        Date date2 = sdf.parse(str);
        System.out.println(sdf.format(date2));
    }
}


Calendar类(日历)

第二代日期类

1. Calendar是一个抽象类,并且Calendar构造器是私有的

2. 可以通过getInstance()获取实例

3. Calendar提供大量的方法和字段

4. Calendar没有提供相应的格式化类,需要程序员自己组合

package com.lili.date;

import java.util.Calendar;

public class Calendar_ {
    public static void main(String[] args) {
        //1.获取日历对象
        Calendar calendar = Calendar.getInstance();
        System.out.println(calendar);
        //2.获取日历对象的某个字段
        System.out.println("年:" + calendar.get(Calendar.YEAR));
        //Calendar.MONTH是从0开始编号的,所以需要加1
        System.out.println("月:" + (calendar.get(Calendar.MONTH) + 1));
        System.out.println("日:" + calendar.get(Calendar.DAY_OF_MONTH));
        System.out.println("时:" + calendar.get(Calendar.HOUR_OF_DAY));
        System.out.println("分:" + calendar.get(Calendar.MINUTE));
        System.out.println("秒:" + calendar.get(Calendar.SECOND));

        System.out.println(calendar.get(Calendar.YEAR) + "年"+
                (calendar.get(Calendar.MONTH) + 1) +"月" +
                calendar.get(Calendar.DAY_OF_MONTH) + "日 " +
                calendar.get(Calendar.HOUR_OF_DAY) + ":" +
                calendar.get(Calendar.MINUTE) + ":" +
                calendar.get(Calendar.SECOND));
    }
}

第三代日期类 

第三代日期常见方法
LocalDate只得到日期

LocalTime只得到时间
LocalDateTime得到日期和时间

package com.lili.date;

import java.time.LocalDateTime;

public class LocalDate_ {
    public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        System.out.println("年:"+now.getYear());
        System.out.println("月:"+now.getMonth()); //月份英文
        System.out.println("月:"+now.getMonthValue()); //月份数
        System.out.println("日:"+now.getDayOfMonth());
        System.out.println("时:"+now.getHour());
        System.out.println("分:"+now.getMinute());
        System.out.println("秒:"+now.getSecond());
    }
}

DateTimeFormatter格式日期类 

package com.lili.date;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDate_ {
    public static void main(String[] args) {
        //第三代日期
        //1.LocalDateTime得到日期和时间
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);

        //2.DateTimeFormatter格式化日期
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");
        System.out.println(dtf.format(now));
    }
}

 plus和minus方法

对当前时间进行加或减

package com.lili.date;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class LocalDate_ {
    public static void main(String[] args) {
        //第三代日期
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss");

        //LocalDateTime提供plus和minus方法对当前时间进行加或减
        LocalDateTime localDateTime = now.plusHours(1);
        System.out.println(dtf.format(localDateTime));
    }
}

Instant时间戳

类似于Date

提供了一系列和Date类转换的方法

Instant->Date

通过Date的静态方法from可以把Instant转为Date

Date->Instant

通过Date对象的toInstant可以把Date转为Instant

package com.lili.date;

import java.time.Instant;
import java.util.Date;

public class Instant_ {
    public static void main(String[] args) {
        //1.通过Instant的静态方法now()获取表示当前时间戳的对象
        Instant now = Instant.now();
        System.out.println(now);
        //2.通过Date的静态方法from可以把Instant转为Date
        Date date = Date.from(now);
        //3.通过Date对象的toInstant可以把Date转为Instant
        Instant instant = date.toInstant();
    }
}

练习题

1. 对字符串指定部分进行反转,public static String reverse(String str, int start, int end); 

要求:异常处理

package com.lili.homework;

public class Homework01 {
    public static void main(String[] args) {
        String str = "hello,java";
        System.out.println("===翻转前===");
        System.out.println(str);

        try {
            str = reverse(str, 6, str.length()-1);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return;
        }

        System.out.println("===翻转后===");
        System.out.println(str);
    }

    public static String reverse(String str, int start, int end) {
        if(!(str!=null && start > 0 && start < end && end <str.length())){
            throw new RuntimeException("参数不正确!");
        }
        char[] s = str.toCharArray();
        char temp = ' ';
        for (int i = start, j = end; i < j; i++, j--) {
            temp = s[i];
            s[i] = s[j];
            s[j] = temp;
        }
        return new String(s);
    }
}

 2. 

本人解法: 

package com.lili.homework;

import java.util.Scanner;

public class Homework02 {
    static Scanner scanner = new Scanner(System.in);

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String userName = "";
        String passWord = "";
        String email = "";

        System.out.print("请输入2~4长度的用户名:");
        try {
            userName = setUserName();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return;
        }

        System.out.print("请输入6位纯数字密码:");
        try {
            passWord = setPassWord();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return;
        }

        System.out.print("邮箱:");
        try {
            email = setEmail();
            System.out.println("注册成功!");
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return;
        }
    }

    public static String setUserName() {
        String userName = scanner.next();
        int len = userName.length();
        if (!(len >= 2 && len <= 4)) {
            throw new RuntimeException("用户名长度应为2~4!");
        }
        return userName;
    }

    public static String setPassWord() {
        String passWord = scanner.next();
        if (!(passWord.length() == 6)) {
            throw new RuntimeException("密码应为6位!");
        }
        try {
            Integer pwd = Integer.parseInt(passWord);
        } catch (NumberFormatException e) {
            throw new RuntimeException("密码应由纯数字组成!");
        }
        return passWord;
    }

    public static String setEmail() {
        String email = scanner.next();
        int i = email.indexOf('@');
        int j = email.indexOf('.');
        if (!(i > -1 && i < j)) {
            throw new RuntimeException("邮箱输入有误,应包含@和.且@在.前!");
        }
        return email;
    }

}

 3. 字符串内存分配问题,看看输出

package com.lili.homework;

public class Homework05 {
    public static void main(String[] args) {
        String s1 = "yuanyuan";
        Animal a = new Animal(s1);
        Animal b = new Animal(s1);
        System.out.println(a == b);  //false
        System.out.println(a.equals(b));  //false
        System.out.println(a.name == b.name); //true

        String s4 = new String("yuanyuan");
        String s5 = "yuanyuan";
        System.out.println(s1 == s4); //false s1指向常量池,s4指向堆
        System.out.println(s4 == s5); //false

        String t1 = "hello" + s1;
        String t2 = "helloyuanyuan";
        System.out.println(t1.intern() == t2); //true

    }
}

class Animal{
    String name;

    public Animal(String name) {
        this.name = name;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Lili_1i1i

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值