Object类 Object类简介 Object类是所有Java类的根父类,如果在类的声明中未明确使用extends关键字指明其父类,则默认父类为java.lang.Object类,也就是说子类可以使用 Object 的所有方法。
1 2 3 4 5 6 7 public class Person { ... } public class Person extends Object { ... }
Object类的方法 方法 简介 getClass()获取对象的运行时 class 对象,通常是和 Java 反射机制搭配使用的 hashCode() 返回当前对象的哈希码值。 equals(Object obj)比较当前对象与指定对象是否相等。 toString()返回当前对象的字符串表示。 clone() 保护方法,实现对象的浅复制,默认的 clone 方法是浅拷贝。 只有实现了 Cloneable 接口才可以调用该方法,否则抛出 CloneNotSupportedException 异常。 notify() 唤醒在此对象监视器上等待的单个线程。 notifyAll() 唤醒在此对象监视器上等待的所有线程。 wait() 导致线程进入等待状态,直到被其他线程通过 notify() 或 notifyAll() 唤醒,该方法只能在同步方法中调用 wait(long timeout) 等待其他线程调用该对象的 notify() 或 notifyAll() 方法,最多等待指定时间(以毫秒为单位) wait(long timeout, int nanos) 等待其他线程调用该对象的 notify() 或 notifyAll() 方法,最多等待指定时间(以毫秒和纳秒为单位) finalize() 在垃圾回收器回收对象之前调用,Jdk9中废弃
toString()方法 (1)Object中定义的toString方法,默认返回格式如下:对象的 class 名称 + @ + hashCode 的十六进制字符串。
1 2 3 4 public String toString () { return getClass().getName() + "@" + Integer.toHexString(hashCode()); }
(2)当我们输出一个对象的引用时,实际上默认调用当前对象的tostring()
1 2 3 4 5 6 7 public class Demo { public static void main (String[] args) { Object o = new Object (); System.out.println(o); System.out.println(o.toString()); } }
(3)如果一个类没有重写toString()方法,那么当打印该类的对象时,会调用Object类中的toString()方法,输出的结果是该对象的引用地址,但是在实际开发中,一般需要输出真实值,所以都会重写toString()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class Demo { public static void main (String[] args) { Person1 person1 = new Person1 (); Person2 person2 = new Person2 (); System.out.println(person1); System.out.println(person2); } } class Person1 { private String name; private int age; } class Person2 { private String name; private int age; @Override public String toString () { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}' ; } }
(4)像String、Data、file、包装类等都重写了Object类中的toString()方法,使得在调用对象的toString()时,返回“实体内容信息”
1 2 3 4 public String toString () { return this ; }
equals()方法 (1)Object中equals()方法用来比较对象的引用地址是否相同,源码如下
1 2 3 public boolean equals (Object obj) { return (this == obj); }
(2)Object中的equals方法使用的是==进行的比较,实际上是比较的两个对象的内存地址是否相同,在现实的开发过程中,通常我们希望比较引用类型的对象内容是否相等,所以一般自定义的Bean都会重写equals()方法
1 2 3 4 5 6 7 8 9 10 11 12 13 class Person { private String name; private int age; @Override public boolean equals (Object o) { if (this == o) return true ; if (o == null || getClass() != o.getClass()) return false ; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } }
(3)像String、Data、File、包装类等都重写了Object类中的equals()方法,调用时是比较的是内容是否一致而不是地址一致
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public boolean equals (Object anObject) { if (this == anObject) { return true ; } if (anObject instanceof String) { String anotherString = (String)anObject; int n = value.length; if (n == anotherString.value.length) { 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 ; }
hashCode()方法 (1)hashCode()方法用于返回对象的哈希码值,哈希码是根据对象的内部状态计算得出的一个整数,用于标识对象的唯一性,通过哈希码,可以快速定位对象在哈希表中的存储位置,从而加快对象的查找速度。
(2)在每个类中,在重写equals方法的时侯,一定要重写hashcode方法。
Object规范要求:如果两个对象通过equals方法比较相等,那么它们的hashCode方法返回的值必须相等。这意味着,在重写equals方法时,如果判断两个对象相等,就必须确保它们的hashCode方法返回相同的值。 equals方法的目的是用于比较两个对象是否在逻辑上相等。默认的equals方法比较的是对象的内存地址,也就是判断两个对象是否引用同一个实例。在重写equals方法时,通常是根据需要比较对象的属性值,而不是仅仅比较内存地址。 hashCode方法返回对象的哈希码值,用于在哈希表等数据结构中高效地存储和检索对象。默认的hashCode方法根据对象的内存地址计算哈希码。 在equals方法与hashCode方法都未重写的情况下,假如有两个对象的内存地址相同,对象的属性值也相同,equals方法会比较内存地址判断为true,hashCode方法根据对象的内存地址计算的哈希码会相同,符合Object规范要求 在equals方法重写但hashCode方法未重写的情况下,假如对象的内存地址不相同,但对象的属性值相同,此时equals方法会比较对象的属性值同样判断为true,但hashCode方法根据对象的内存地址计算的哈希码可能不相同,不符合Object规范要求 getClass()方法 (1)Object中的getClass()方法用于获取对象的运行时对象的类,方法的返回值是Class类型
1 public final native Class<?> getClass();
(2)万物皆对象,JVM会将字节码文件加载到其内部一个叫做方法区的地方,然后会在堆中创建这个字节码文件对应的对象,这个对象是java.lang.Class类型的,在JVM中每个字节码文件只有一个对应的Class对象,可以通过Object中提供的getClass方法来获取这个对象。
1 2 Object obj = new Object ();Class<?> clazz = obj.getClass();
(3)Class clazz = obj.getClass();根据clazz可以获取该对象的所有成员方法、成员方法等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 public class ClassUtil { public static void printClassMethodMessage (Object obj) { Class clazz = obj.getClass(); System.out.println("类的名称是:" + clazz.getName()); Method[] declaredMethods = clazz.getDeclaredMethods(); Method[] ms = clazz.getMethods(); for (int i = 0 ; i < ms.length; i++) { Class returnType = ms[i].getReturnType(); System.out.print(returnType.getName() + " " ); System.out.print(ms[i].getName() + "(" ); Class[] paramTypes = ms[i].getParameterTypes(); for (Class class1 : paramTypes) { System.out.print(class1.getName() + "," ); } System.out.println(")" ); } } public static void printFieldMessage (Object obj) { Class clazz = obj.getClass(); Field[] fields = clazz.getFields(); Field[] declaredFields = clazz.getDeclaredFields(); for (Field field : declaredFields) { Class fieldType = field.getType(); String typeName = fieldType.getName(); String fieldName = field.getName(); System.out.println(typeName + " " + fieldName); } } public static void printConMessage (Object obj) { Class clazz = obj.getClass(); Constructor[] constructors = clazz.getConstructors(); Constructor[] declaredConstructors = clazz.getDeclaredConstructors(); for (Constructor constructor : declaredConstructors) { System.out.print(constructor.getName() + "(" ); Class[] paramTypes = constructor.getParameterTypes(); for (Class class1 : paramTypes) { System.out.print(class1.getName() + "," ); } System.out.println(")" ); } } }
clone()方法 (1)clone()方法是Object类中的保护方法,用于实现对象的浅复制(浅拷贝)。只有实现了 Cloneable 接口才可以调用该方法,否则抛出 CloneNotSupportedException 异常。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 @Getter @Setter @NoArgsConstructor @AllArgsConstructor class Person implements Cloneable { private String name; private List<String> hobbies; @Override public Object clone () throws CloneNotSupportedException { return super .clone(); } } class Main { public static void main (String[] args) throws CloneNotSupportedException { List<String> hobbies = new ArrayList <>(); hobbies.add("读书" ); hobbies.add("游泳" ); Person person1 = new Person ("小明" , hobbies); Person person2 = (Person) person1.clone(); person2.setName("小刚" ); person2.getHobbies().add("唱歌" ); System.out.println(person1.getName()); System.out.println(person2.getName()); System.out.println(person1.getHobbies()); System.out.println(person2.getHobbies()); } }
(2)如果需要实现深拷贝,则需要在具体的对象类中重写clone()方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 @Getter @Setter @NoArgsConstructor @AllArgsConstructor class Person implements Cloneable { private String name; private List<String> hobbies; @Override public Object clone () { List<String> clonedHobbies = new ArrayList <>(this .hobbies); return new Person (this .name, clonedHobbies); } } class Main { public static void main (String[] args) { List<String> hobbies = new ArrayList <>(); hobbies.add("读书" ); hobbies.add("游泳" ); Person person1 = new Person ("小明" , hobbies); Person person2 = (Person) person1.clone(); person2.setName("小刚" ); person2.getHobbies().add("唱歌" ); System.out.println(person1.getName()); System.out.println(person2.getName()); System.out.println(person1.getHobbies()); System.out.println(person2.getHobbies()); } }
字符串类 字符串相关类 (1)String类、StringBuffer类、StringBuilder类是三个字符串相关类。
字符串相关类 简介 String 不可变字符序列,存储在字符串常量池中,内容无法修改 StringBuffer 底层是字符数组,系统会对该数组进行扩容,内容频繁修改字符串的情况考虑使用StingBuffer StringBuilder 与StringBuffer非常类似,均代表可变的字符序列,通过API可以看到提供相关功能的方法也一样
(2)String类的对象代表不可变的字符序列,StringBuilder类和StringBuffer类代表可变字符序列
(3)String类用来表示字符串,一旦被声明,值就不能被改变,如果需要改变,就要重新创建新的String对象,适用于存储较短的字符串或者是不需要频繁修改的字符串。为了方便操作字符串,JDK引入了StringBuffer来解决,StringBuffer是可变的字符串,底层使用的数组进行动态扩容,类中每个公开方法都使用了synchronized关键字修饰,所有是线程同步安全的,适用于多线程的场景,而StringBuilder与StringBuffer相似,也是可变字符串,不同的是类中方法只有少部分使用了synchronized关键字修饰,不能确保线程安全,适用于单线程的场景
String类 字符串初始化 在操作String类之前,首先需要对String类进行初始化,可以通过常量直接赋值对String类进行初始化,或者使用String的构造方法来初始化字符串对象
构造方法 功能描述 String() 创建一个内容为空的字符串 String(char[] value) 根据指定的字符数组创建对象 String(String value) 根据指定的字符串内容创建对象
1 2 3 4 5 6 7 8 String str1="abc" ; String str2=new String (); String str3=new String ("小明" ); char [] charArray=new char []{'A' ,'B' ,'C' };String str4=new String (charArray);
字符串创建后值不可改变 String是引用数据类型,通过源码可以看到String类前面加了final修饰,因此String类是不能够被继承的。将其设置为不能被继承的原因是为了减少歧义
1 public final class String implements java .io.Serializable, Comparable<String>, CharSequence {...}
String创建好之后值是不可以被改变的,这里指的是在堆中的字符串的值是不可以被改变,不可变的主要原因是其底层使用了一个final修饰的char字符数组(Jdk8中)。在Jdk9之后版本中,String底层使用的是final修饰的byte字节数组
1 2 3 4 5 6 7 8 9 10 11 12 public class StringTest { public static void main (String[] args) { String str = "小明" ; change(str); System.out.println(str); } public static void change (String str) { str = "小刚" ; System.out.println("修改为:" + str); } }
常用方法 方法名 描述 split(String regex) 字符串分隔,分割字符串为字符串数组 substring(int beginIndex, int endIndex) 字符串截取,截取[beginIndex,endIndex)位置字符串,包含beginIndex下标元素,不包含endIndex下标元素 concat(String str) 字符串拼接,将指定的字符串连接到原字符串的末尾 replace(char oldChar, char newChar) 字符串替换,替换字符串中的字符 trim() 字符串去空白,去除字符串两端空白 toLowerCase() 字符串大写转小写,将字符串转换为小写字母 toUpperCase() 字符串小写转大写,将字符串转换为大写字母 indexOf(char ch) 字符串查找,返回指定字符的索引 charAt(int index) 字符串查找,返回指定索引处的字符 equals() 字符串比较,判断当前字符串与指定的对象是否相等,如果相等则返回true,否则返回false。 format(String format, Object… args) 字符串格式化,使用指定的格式字符串和参数进行格式化操作。 length() 返回字符串的长度,返回字符串的长度,即包含的字符数量。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 public class StringMethodsExample { @Test public void testSplit () { String text = "你好,世界!" ; String[] parts = text.split("," ); System.out.println("数组长度: " + parts.length); System.out.println("部分 1: " + parts[0 ]); System.out.println("部分 2: " + parts[1 ]); } @Test public void testSubstring () { String text = "你好,世界!" ; String substring = text.substring(3 , 5 ); System.out.println("截取结果: " + substring); } @Test public void testConcat () { String text = "你好" ; String result = text.concat(",GPT-3.5!" ); System.out.println("拼接结果: " + result); } @Test public void testReplace () { String text = "你好,世界!" ; String replacedText = text.replace("," , "-" ); System.out.println("替换后的字符串: " + replacedText); } @Test public void testTrim () { String text = " 你好,世界! " ; String trimmedText = text.trim(); System.out.println("去除空白后的字符串: " + trimmedText); } @Test public void testToLowerCase () { String text = "HELLO,WORLD!" ; String lowerCaseText = text.toLowerCase(); System.out.println("小写字母字符串: " + lowerCaseText); } @Test public void testToUpperCase () { String text = "hello,world!" ; String upperCaseText = text.toUpperCase(); System.out.println("大写字母字符串: " + upperCaseText); } @Test public void testIndexOf () { String text = "你好,世界!" ; int index = text.indexOf("世界" ); System.out.println("索引位置: " + index); } @Test public void testCharAt () { String text = "你好,世界!" ; char character = text.charAt(3 ); System.out.println("索引位置为 3 的字符: " + character); } @Test public void testEquals () { String text1 = "你好" ; String text2 = "你好" ; boolean isEqual = text1.equals(text2); System.out.println("两个字符串是否相等? " + isEqual); } @Test public void testFormat () { String name = "小明" ; int age = 25 ; String formatted = String.format("我叫%s,今年%d岁。" , name, age); System.out.println("格式化后的字符串: " + formatted); } @Test public void testLength () { String text = "你好,世界!" ; int length = text.length(); System.out.println("字符串长度: " + length); } }
StringBuffer类 StringBuffer类简介 (1)由于字符串是常量,因此一旦创建,其内容和长度是不可改变的。如果需要对一个字符串进行修改,则只能创建新的字符串。为了便于对字符串的修改,JDK中提供了一个StringBuffer类(也称字符串缓冲区),与String类最大的区别在于StringBuffer的内容和长度都是可以改变的。
(2)StringBuffer 类提供了 3 个构造方法来创建一个字符串
构造方法 功能描述 StringBuffer() 构造一个空的字符串缓冲区,并且初始化为 16 个字符的容量 StringBuffer(int length) 创建一个空的字符串缓冲区,并且初始化为指定长度 length 的容量 StringBuffer(String str) 创建一个字符串缓冲区,并将其内容初始化为指定的字符串内容 str 字符串缓冲区的初始容量为 16 加上字符串 str 的长度
(3)StringBuffer是线程安全的,所有公开方法都是 synchronized 修饰,在多线程程序中也可以很方便的进行使用
StringBuffer工作原理 StringBuffer 对象创建:当我们创建一个 StringBuffer 对象时,它会在内部初始化一个默认大小的字符数组,并保留一些额外的空间以便后续的字符串添加操作。 字符串的添加和修改:通过调用 StringBuffer 的 append()、insert()、delete() 等方法,我们可以向 StringBuffer 对象中添加、插入或删除字符。这些操作会在字符数组的末尾或指定位置进行。 自动扩容:当我们进行字符串添加操作时,如果当前内部字符数组的容量不足以容纳新的字符串,StringBuffer 会自动扩容。它会创建一个更大的字符数组,并将原始字符数组的内容复制到新数组中。 性能优化:为了提高性能,StringBuffer 内部使用了一些优化策略。例如,它会预分配一些额外的空间以减少频繁的扩容操作,同时也会使用一些技巧来避免不必要的字符复制。 StringBuffer类的常用方法 常用方法 简介 append() 字符串拼接(增) delete() 删除指定位置的内容(删) deleteCharAt() 移除序列中指定位置的字符(删) replace() 用指定字符串替换指定范围内的字符(改) insert() 在指定位置插入(改) reverse() 反转,把当前字符序列逆转(改) setCharAt() 替换字符,用于在字符串的指定索引位置替换一个字符(改) charAt() 返回指定位置的字符(查) length() 返回长度(查)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public class StringBufferTest { public static void main (String[] args) { StringBuffer stringBuffer = new StringBuffer ("Hello" ); stringBuffer.append(" World" ); System.out.println(stringBuffer); stringBuffer.delete(5 , 11 ); System.out.println(stringBuffer); stringBuffer.deleteCharAt(1 ); System.out.println(stringBuffer); stringBuffer.replace(1 , 2 , "i" ); System.out.println(stringBuffer); stringBuffer.insert(1 , "e" ); System.out.println(stringBuffer); stringBuffer.reverse(); System.out.println(stringBuffer); stringBuffer.setCharAt(0 , 'H' ); System.out.println(stringBuffer); char c = stringBuffer.charAt(1 ); System.out.println(c); int length = stringBuffer.length(); System.out.println(length); } }
StringBuilder类 StringBuilder与StringBuffer相似,也是可变字符串,不同的是类中方法只有少部分使用了synchronized关键字修饰,不能确保线程安全,适用于单线程的场景
包装类 什么是包装类? 在Java中,包装类(Wrapper Class)是一种用于将基本数据类型转换为对象的类。
为什么会有包装类? Java是一个面向对象的编程语言,但是Java中的八种基本数据类型却是不面向对象的,无法直接参与面向对象的操作,于是Java提供了八种基本数据类型对应的包装类(封装类),使得基本数据类型的变量具有类的特征。有了类的特点,就可以调用类中的方法,Java才是真正的面向对象。
包装类分类 除了Integer和Character类以外,其它六个类的类名和基本数据类型一致,只是类名的第一个字母大写即可
基本数据类型 占用存储空间(字节) 默认值 包装类 byte 1 0 Byte short 2 0 Short int 4 0 Integer long 8 0L Long float 4 0.0f Float double 8 0.0d Double char 2 ‘\u0000’(空字符) Character boolean 1 false Boolean
类型转换 自动装箱 :基本数据类型-->包装类,将 基本数据类型 封装为对象类型,来符合Java的面向对象的思想。自动拆箱 :包装类-->基本数据类型,是指包装类对象赋给一个相对应基本数据类型的变量自动装箱 基本数据类型–>包装类(装箱)
1 2 3 4 5 6 7 8 9 10 int num = 500 ; Integer newNum = new Integer (num);Integer num = Integer.values(0 );int a = 13 ;Integer b = a;boolean c = true ;Boolean d = c;
基本数据类型、包装类–>字符串(装箱)
1 2 3 4 String str = String.valueOf(1.23f );String intStr = 5 + "" ;
自动拆箱 包装类–>基本数据类型(拆箱)
1 2 3 4 5 6 Integer a = new Integer (12 );int b = a.intValue();Integer a = 13 ;int b = a;
字符串–>基本数据类型(拆箱)
1 2 3 4 int i = new Integer ("123" );int num = Integer.parseInt("123" );
包装类型的缓存机制 (1)Java 包装类的缓存机制,是在Java 5中引入的一个有助于节省内存、提高性能的功能
(2)Java 基本类型除了Float 和 Double 外,其他包装数据类型都使用了缓存机制来提升性能
(3)缓存机制实现方式是在类初始化时,提前创建好会频繁使用的包装类对象,当需要使用某个包装类的对象时,如果该对象包装的值在缓存的范围内,就返回缓存的对象,否则就创建新的对象并返回。
(4)缓存机制只有在自动装箱时有效,使用构造函数创建对象不适用,因为每次new会创建新的对象
(5)自动装箱会从缓存池中取对象,两种浮点数类型的包装类Float,Double并没有实现常量池技术,在其他包装类中,包装类Byte,Short,Integer,Long 默认创建了区间为 [-128, 127] 的缓存池缓存数据,包装类Character 创建了区间在 [0,127] 范围的缓存池缓存数据,包装类Boolean 直接返回 True or False。缓存的基本数据类型值的范围如下
基本数据类型 包装类 缓存范围 byte Byte [-128, 127] short Short [-128, 127] char Character [0,127] int Integer [-128, 127] long Long [-128, 127] float Float 无 double Double 无 boolean Boolean True、False
(6)包装类缓存原理:使用自动装箱将基本类型转为封装类对象这个过程其实底层实现是调用封装类的valueOf方法
1 2 3 4 5 6 7 public static Integer valueOf (int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer (i); }
IntegerCache是Integer类中定义的一个private static的内部类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 private static class IntegerCache { static final int low = -128 ; static final int high; static final Integer cache[]; static { int h = 127 ; String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high" ); if (integerCacheHighPropValue != null ) { try { int i = parseInt(integerCacheHighPropValue); i = Math.max(i, 127 ); h = Math.min(i, Integer.MAX_VALUE - (-low) -1 ); } catch ( NumberFormatException nfe) { } } high = h; cache = new Integer [(high - low) + 1 ]; int j = low; for (int k = 0 ; k < cache.length; k++) cache[k] = new Integer (j++); assert Integer.IntegerCache.high >= 127 ; } private IntegerCache () {} }
数值处理类 BigInteger类 (1)Integer包装类能存储的最大值是有限的。如果要表示再大的整数,不管是基本数据类型还是包装类都无能为力,更不用说运算了。
(2)java.math包下的BigInteger用于处理任意精度的整数,可以对超过Integer范围内的数据进行运算。
(3)BigInteger 提供所有 Java 的基本整数操作符的对应物,并提供 java.lang.Math 的所有相关方法。
(4)BigInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、 位操作以及一些其他操作。
(5)成员方法
方法 简介 add(BigInteger val) 加法 subtract(BigInteger val) 减法 multiply(BigInteger val) 乘法 divide(BigInteger val) 除法 divideAndRemainder(BigInteger val) 带余除法,返回两个BigInteger,第一个是商,第二个是余数 pow(int exponet) 进行取参数的 exponet 次方操作 negate() 取相反数 shiftLegt(int n) 将数字左移 n 位,如果 n 为负数,做右移操作 shiftRight(int n) 将数字右移 n 位,如果 n 为负数,做左移操作 compareTo(BigInteger val) 做数字比较操作 max(BigInteger val) 返回较大的数值
BigDecimal类 (1)一般的float类型和double可以用来做科学计算或工程计算,但由于在运算的时候,float类型和double很容易丢失精度,在商业计算中, 要求数字精度比较高,为了能精确的表示、计算浮点数,Java提供了BigDecimal类
(2)BigDecimal用于处理任意精度的十进制浮点数,可以解决浮点型数据运算数据丢失问题,在金融行业可能会使用到该类
(3)成员方法
方法 简介 add(BigDecimal value); 加法 subtract(BigDecimal value); 减法 multiply(BigDecimal value); 乘法 divide(BigDecimal value); 除法 divide(BigDecimal divisor, int scale, int roundingMode) 第一参数表示除数, 第二个参数表示小数点后保留位数,第三个参数表示舍入模式,只有在作除法运算或四舍五入时才用到舍入模式
(4)舍入模式介绍
模式 简介 ROUND_UP 向远离零的方向舍入。舍弃非零部分,并将非零舍弃部分相邻的一位数字加一 ROUND_DOWN 向接近零的方向舍入。舍弃非零部分,同时不会非零舍弃部分相邻的一位数字加一,采取截取行为 ROUND_CEILING 向正无穷的方向舍入。如果为正数,舍入结果同ROUND_UP一致;如果为负数,舍入结果同ROUND_DOWN一致。注意:此模式不会减少数值大小 ROUND_FLOOR 向负无穷的方向舍入。如果为正数,舍入结果同ROUND_DOWN一致;如果为负数,舍入结果同ROUND_UP一致。注意:此模式不会增加数值大小 ROUND_HALF_UP 四舍五入 ROUND_HALF_DOWN 五舍六入 ROUND_HALF_EVEN 向“最接近”的数字舍入,如果与两个相邻数字的距离相等,则相邻的偶数舍入。如果舍弃部分左边的数字奇数,则舍入行为与ROUND_HALF_UP相同,如果为偶数,则舍入行为与ROUND_HALF_DOWN相同。注意:在重复进行一系列计算时,此舍入模式可以将累加错误减到最小。此舍入模式也称为“银行家舍入法”,主要在美国使用。四舍六入,五分两种情况,如果前一位为奇数,则入位,否则舍去 ROUND_UNNECESSARY 断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException
Math类 java.lang.Math提供了一系列静态方法用于科学计算,其方法的参数和返回 值类型一般为double型
方法 简介 abs 绝对值 acos,asin,atan,cos,sin,tan 三角函数 sqrt 平方根 pow(double a,doble b) a的b次幂 log 自然对数 exp e为底指数 max(double a,double b) 最大数 min(double a,double b) 最小数 random() 返回0.0到1.0的随机数 long round(double a) double型数据a转换为long型(四舍五入) toDegrees(double angrad) 弧度—>角度 toRadians(double angdeg) 角度—>弧度
1 2 3 4 System.out.println(Math.max(10 ,2 )); System.out.println(Math.min(10 , 5 )); System.out.println(Math.abs(-20 )); System.out.println(Math.random());
Random类 Random 类是 Java 中提供的一个用于生成随机数的工具类。它可以生成不同类型的随机数,包括整数、浮点数和布尔值
生成随机整数 1 2 3 4 5 6 7 8 9 public class RandomExample { public static void main (String[] args) { Random random = new Random (); int randomNumber = random.nextInt(100 ); System.out.println("随机整数:" + randomNumber); } }
生成随机浮点数 1 2 3 4 5 6 7 8 9 public class RandomExample { public static void main (String[] args) { Random random = new Random (); double randomDouble = random.nextDouble(); System.out.println("随机浮点数:" + randomDouble); } }
生成随机布尔值 1 2 3 4 5 6 7 8 9 public class RandomExample { public static void main (String[] args) { Random random = new Random (); boolean randomBoolean = random.nextBoolean(); System.out.println("随机布尔值:" + randomBoolean); } }
日期时间类 JDK8前的日期时间类 System类提供的public static long currentTimeMillis()用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
1 2 long time=System.currentTimeMillis();System.out.println(time);
Date类 (1)java.util.Date类
构造器 简介 Date() 使用无参构造器创建的对象可以获取本地当前时间。 Date(long date) 创建指定毫秒数的Date对象
1 2 3 4 5 6 7 8 9 10 @Test public void test () { Date date1 = new Date (); System.out.println(date1.toString()); System.out.println(date1.getTime()); System.out.println(date1.toLocaleString()); Date date2 = new Date (123456L ); System.out.println(date2.toString()); }
(2)java.sql.Date是java.util.Date类的子类,对应着数据库中的日期类型的变量
1 2 3 4 5 @Test public void test () { java.sql.Date date = new java .sql.Date(123456L ); System.out.println(date); }
(1)java.text.DateFormat 是日期/时间格式化子类的抽象类,通过这个类可以完成日期和文本之间的转换,也就是可以在Date对象与String对象之间进行来回转换
转换 简介 格式化(日期 -> 文本) 按照指定的格式,从Date对象转换为String对象。 解析(文本-> 日期) 按照指定的格式,从String对象转换为Date对象。
(2)DateFormat类是一个抽象类,无法直接创建对象使用,可以使用DateFormat类的子类SimpleDateFormat
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Test public void test () throws ParseException { SimpleDateFormat dateFormat1 = new SimpleDateFormat (); String format1 = dateFormat1.format(new Date ()); System.out.println(format1); Date parse1 = dateFormat1.parse("20-1-6 下午1:00" ); System.out.println(parse1); SimpleDateFormat dateFormat2 = new SimpleDateFormat ("yyyy-MM-dd hh:mm:ss" ); String format2 = dateFormat2.format(new Date ()); System.out.println(format2); Date parse2 = dateFormat2.parse("2020-01-06 01:34:09" ); System.out.println(parse2); }
Calendar类 (1)java.util.Calendar是日历类,在Date后出现,替换掉了许多Date的方法。该类是一个抽象基类,将所有可能用到的时间信息封装为静态成员变量,方便获取,主用用于完成日期字段之间相互操作的功能。
(2)常用方法
常用方法 简介 public int get(int field) 返回给定日历字段的值。 public void set(int field, int value) 将给定的日历字段设置为给定值。 public abstract void add(int field, int amount) 根据日历的规则,为给定的日历字段添加或减去指定的时间量。 public Date getTime() 返回一个表示此Calendar时间值(从历元到现在的毫秒偏移量)的Date对象。
(3)Calendar类中提供很多成员常量,代表给定的日历字段
字段值 含义 YEAR 年 MONTH 月(从0开始,可以+1使用 DAY_OF_MONTH 月中的天(几号) HOUR 时(12小时制) HOUR_OF_DAY 时(24小时制) MINUTE 分 SECOND 秒 DAY_OF_WEEK 周中的天(周几,周日为1,可以-1使用)
JDK8后的日期时间类 针对JDK8以前的日期类设计不足,比如不支持时区、线程不安全等,JDK8引入了java.time包来作为新的日期处理类
属性 含义 Instant 代表的是时间相当于Date LocalDate 代表日期,比如2022-01-14 LocalTime 代表时间,比如12:20:30 LocalDateTime 代表具体时间,比如2022-01-14 12:20:30 ZonedDateTime 代表一个包含时区的完整的日期时间 Period 代表时间段 ZoneOffset 代表时区偏移量,比如+8:00 Clock 代表时钟,比如获取美国纽约的时间 DateTimeFormatter 日期和字符串格式转换
LocalDate类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class LocalDateExample { public static void main (String[] args) { LocalDate currentDate = LocalDate.now(); System.out.println("当前日期: " + currentDate); LocalDate specificDate = LocalDate.of(2023 , 7 , 1 ); System.out.println("指定的日期: " + specificDate); int year = specificDate.getYear(); int month = specificDate.getMonthValue(); int day = specificDate.getDayOfMonth(); System.out.println("年: " + year + " 月: " + month + " 日: " + day); LocalDate nextDay = specificDate.plusDays(1 ); System.out.println("下一天日期: " + nextDay); } }
LocalTime类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class LocalTimeExample { public static void main (String[] args) { LocalTime currentTime = LocalTime.now(); System.out.println("当前时间: " + currentTime); LocalTime specificTime = LocalTime.of(9 , 30 , 0 ); System.out.println("指定的时间: " + specificTime); int hour = specificTime.getHour(); int minute = specificTime.getMinute(); int second = specificTime.getSecond(); System.out.println("小时: " + hour + " 分钟: " + minute + " 秒: " + second); LocalTime nextHour = specificTime.plusHours(1 ); System.out.println("下一个小时时间: " + nextHour); } }
LocalDateTime类 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class LocalDateTimeExample { public static void main (String[] args) { LocalDateTime currentDateTime = LocalDateTime.now(); System.out.println("当前日期和时间: " + currentDateTime); LocalDateTime specificDateTime = LocalDateTime.of(2023 , 7 , 1 , 9 , 30 , 0 ); System.out.println("指定的日期和时间: " + specificDateTime); int year = specificDateTime.getYear(); int month = specificDateTime.getMonthValue(); int day = specificDateTime.getDayOfMonth(); int hour = specificDateTime.getHour(); int minute = specificDateTime.getMinute(); int second = specificDateTime.getSecond(); System.out.println("年: " + year + " 月: " + month + " 日: " + day + " 小时: " + hour + " 分钟: " + minute + " 秒: " + second); LocalDateTime nextDay = specificDateTime.plusDays(1 ); System.out.println("下一天日期和时间: " + nextDay); } }
Instant类 (1)时间线上的一个瞬时点。 这可能被用来记录应用程序中的事件时间戳。
(2)时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01 日08时00分00秒)起至现在的总秒数。
(3)常用方法
常用方法 描述 now() 获取本初子午线对应的标准时间 atOffset() 添加时间的偏移量 toEpochMilli() 获取自1970年1月1日0时0分0秒(UTC)开始的毫秒数 ofEpochMilli() 通过给定的毫秒数,获取Instant示例
(4)代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 Instant time1 = Instant.now();System.out.println(time1); OffsetDateTime time2 = time1.atOffset(ZoneOffset.ofHours(8 ));System.out.println(time2); long time3 = time1.toEpochMilli();System.out.println(time3); Instant time4 = time1.ofEpochMilli(1641470139866L );System.out.println(time4);
(1)用来格式化与解析日期或时间,类似SimpleDateFormat,不仅可以将日期、时间对象格式化成字符串,还能将特定格式的字符串解析成日期、时间对象
(2)获得DateTimeFormatter对象的方式
方式 简介 预定义的标准格式 使用静态常量创建DateTimeFormatter格式器,在DateTimeFormatter类中包含大量的静态常量,如BASIC_ISO_DATE、ISO_LOCAL_DATE、ISO_LOCAL_TIME等,通过这些静态常量都可以获取DateTimeFormatter实例 本地化相关的格式 使用不同风格的枚举值来创建DateTimeFormatter格式器,在FormatStyle类中定义了FULL、LONG、MEDIUM和SHORT四个枚举值,它们表示日期和时间的不同风 自定义的格式 根据模式字符串创建DateTimeFormatter格式器
(3)代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @Test public void test () { LocalDateTime date = LocalDateTime.now(); DateTimeFormatter dtf1 = DateTimeFormatter.ISO_DATE_TIME; System.out.println(dtf1.format(date)); TemporalAccessor parse1 = dtf1.parse("2020-01-06T20:13:08.006" ); System.out.println(parse1); DateTimeFormatter dtf2 = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM); System.out.println(dtf2.format(date)); TemporalAccessor parse2 = dtf2.parse("2020-01-06T20:13:08.006" ); System.out.println(parse2); DateTimeFormatter dtf3 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss" ); System.out.println(dtf3.format(date)); TemporalAccessor parse3 = dtf3.parse("2020-01-06T20:13:08.006" ); System.out.println(parse3); }
系统相关类 System类简介 (1)System类代表系统,位于java.lang包,系统级的很多属性和控制方法都放置在该类的内部。
(2)由于该类的构造器是private的,所以无法创建该类的对象,也就是无法实例化该类。其内部的成员变量和成员方法都是static的,所以也可以很方便的进行调用
(3)System类内部包含in、out和err三个成员变量,分别代表标准输入流(键盘输入),标准输出流(显示器)和标准错误输出流(显示器)。
System类成员方法 方法 简介 currentTimeMillis() 返回当前的计算机时间 exit(int status) 退出程序,其中status的值为0代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。 gc() 请求系统进行垃圾回收 getProperty(String key) 获得系统中属性名为key的属性对应的值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 String javaVersion = System.getProperty("java.version" );System.out.println(javaVersion); String javaHome = System.getProperty("java.home" );System.out.println(javaHome); String osName = System.getProperty("os.name" );System.out.println(osName); String osVersion = System.getProperty("os.version" );System.out.println(osVersion); String userName = System.getProperty("user.name" );System.out.println(userName); String userHome = System.getProperty("user.home" );System.out.println(userHome); String userDir = System.getProperty("user.dir" );System.out.println(userDir);
Scanner类 Scanner 类是 Java 中提供的一个用于读取用户输入的工具类。它可以从不同的数据源(如键盘或文件)中获取用户输入,并将输入内容转换为程序中需要的不同类型的变量
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class ScannerExample { public static void main (String[] args) { Scanner scanner = new Scanner (System.in); System.out.print("请输入一个整数:" ); int num = scanner.nextInt(); System.out.println("您输入的整数是:" + num); System.out.print("请输入一个字符串:" ); String str = scanner.next(); System.out.println("您输入的字符串是:" + str); scanner.close(); } }