Java常用类详解:从Object到Random,一文掌握Java核心类库

java-API_常用类介绍及运用 java - API_常用类 1.概述 API应用程序编程接口 API文档:是对java预先定义的类或接口功能和方法功能的说明文档,目的是提供给开发人员进行使用帮助说明 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-01vxvAbl-1605272759421)(C:\Users\dell\Desktop\api介绍.jpg)] 2.基本数据类型包装类 Java语言是一个面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不 阅读详情

一、Object类 - 万类之祖

1.1 Object类的作用

Object是Java中所有类的根类,每个类都直接或间接继承自Object。当你定义一个类时,如果没有显式地指定父类,Java编译器会自动让它继承Object类。

继承关系示例:

// 等价写法1
class MyClass extends Object {
    // ...
}

// 等价写法2(编译器自动添加extends Object)
class MyClass {
    // ...
}

1.2 Object类的核心方法

equals()方法
// Object类中的原始实现
public boolean equals(Object obj) {
    return (this == obj);  // 比较对象的内存地址
}

// 实际应用场景:
Object obj1 = new Object();
Object obj2 = new Object();
Object obj3 = obj1;

System.out.println(obj1.equals(obj2));  // false,内存地址不同
System.out.println(obj1.equals(obj3));  // true,引用同一个对象

为什么需要重写equals()?

  • Object的默认equals()只比较内存地址

  • 实际开发中我们需要比较对象的内容是否相等

  • 比如:两个学生对象,学号相同就应该是同一个学生

正确重写equals()的步骤:

public class Student {
    private String name;
    private int age;
    
    @Override
    public boolean equals(Object obj) {
        // 1. 检查是否同一个对象
        if (this == obj) return true;
        
        // 2. 检查是否为null
        if (obj == null) return false;
        
        // 3. 检查类型是否相同
        if (getClass() != obj.getClass()) return false;
        
        // 4. 类型转换
        Student other = (Student) obj;
        
        // 5. 比较关键属性
        return age == other.age && Objects.equals(name, other.name);
    }
}
hashCode()方法
// Object类中的原始实现
public native int hashCode();  // native表示用C/C++实现

// 哈希值的应用场景:
// 1. HashMap、HashSet等集合的快速查找
// 2. 对象在散列表中的存储位置

哈希冲突演示:

String s1 = "通话";
String s2 = "重地";
System.out.println(s1.hashCode());  // 1179395
System.out.println(s2.hashCode());  // 1179395
System.out.println(s1.equals(s2));  // false
toString()方法
// Object类中的原始实现
public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

// 示例输出:com.example.Student@1b6d3586

为什么要重写toString()?

// 重写前
Student student = new Student("张三", 20);
System.out.println(student);  // 输出:Student@1b6d3586

// 重写后
@Override
public String toString() {
    return "Student{name='" + name + "', age=" + age + "}";
}
// 输出:Student{name='张三', age=20}

1.3 hashCode()和equals()的关系(面试重点)

重要规则:

  1. equals相等,hashCode必须相等

  2. hashCode相等,equals不一定相等

  3. 重写equals()必须重写hashCode()

违反规则的后果:

public class BadStudent {
    private String name;
    private int age;
    
    // 只重写equals,不重写hashCode
    @Override
    public boolean equals(Object obj) {
        // ... equals实现
    }
    
    public static void main(String[] args) {
        BadStudent s1 = new BadStudent("张三", 20);
        BadStudent s2 = new BadStudent("张三", 20);
        
        Set<BadStudent> set = new HashSet<>();
        set.add(s1);
        set.add(s2);
        
        System.out.println(set.size());  // 可能是2!应该为1
    }
}

正确实现:

@Override
public int hashCode() {
    // 使用31的原因:
    // 1. 31是素数,减少哈希冲突
    // 2. 31 * i = (i << 5) - i,JVM可以优化
    int result = 17;
    result = 31 * result + (name == null ? 0 : name.hashCode());
    result = 31 * result + age;
    return result;
    
    // Java 7+ 简化写法
    // return Objects.hash(name, age);
}

1.4 == 和 equals 的对比

比较维度

== 运算符

equals() 方法

基本类型​

比较值是否相等

不可用

引用类型​

比较内存地址是否相同

比较对象内容是否相等(可重写)

null处理​

可与null比较

需先判空,否则NPE

性能​

O(1),直接比较

取决于实现,可能较慢

重写性​

不可重写

可重写

示例​

"hello" == "hello"

"hello".equals("hello")

特殊案例:String常量池

String s1 = "hello";  // 常量池
String s2 = "hello";  // 常量池
String s3 = new String("hello");  // 堆内存
String s4 = new String("hello");  // 堆内存

System.out.println(s1 == s2);       // true,指向常量池同一对象
System.out.println(s1 == s3);       // false,内存地址不同
System.out.println(s3 == s4);       // false,不同对象
System.out.println(s1.equals(s3));  // true,内容相同
System.out.println(s3.equals(s4));  // true,内容相同

二、包装类(Wrapper Classes)

2.1 基本类型与包装类的对应关系

基本类型

包装类

字节数

取值范围

默认值

byte

Byte

1

-128 ~ 127

0

short

Short

2

-32768 ~ 32767

0

int

Integer

4

-2³¹ ~ 2³¹-1

0

long

Long

8

-2⁶³ ~ 2⁶³-1

0L

float

Float

4

±3.4E-38 ~ ±3.4E+38

0.0f

double

Double

8

±1.7E-308 ~ ±1.7E+308

0.0d

char

Character

2

'\u0000' ~ '\uffff'

'\u0000'

boolean

Boolean

1

true/false

false

2.2 Integer类详解

构造方法
// 1. 通过int值创建
Integer i1 = new Integer(100);

// 2. 通过字符串创建(可能抛出NumberFormatException)
Integer i2 = new Integer("100");

// 3. 推荐使用valueOf(有缓存优化)
Integer i3 = Integer.valueOf(100);
Integer i4 = Integer.valueOf("100");
常用方法
// 类型转换
Integer num = Integer.valueOf(100);
byte b = num.byteValue();      // 100
short s = num.shortValue();    // 100
int i = num.intValue();        // 100
long l = num.longValue();      // 100L
float f = num.floatValue();    // 100.0f
double d = num.doubleValue();  // 100.0d

// 字符串转换
String str = num.toString();           // "100"
int parseInt = Integer.parseInt("100");  // 100
Integer valueOf = Integer.valueOf("100"); // Integer(100)

// 进制转换
System.out.println(Integer.toBinaryString(10));  // "1010" 二进制
System.out.println(Integer.toOctalString(10));    // "12"   八进制
System.out.println(Integer.toHexString(10));      // "a"    十六进制

// 比较
Integer a = 100, c = 200;
System.out.println(a.equals(100));    // true
System.out.println(a.compareTo(200)); // -1 (a < c)
System.out.println(Integer.compare(a, c)); // -1

2.3 自动装箱与拆箱(AutoBoxing & Unboxing)

什么是自动装箱拆箱?
// 自动装箱:基本类型 → 包装类型
Integer a = 100;  // 编译器转换为:Integer.valueOf(100)

// 自动拆箱:包装类型 → 基本类型
int b = a;        // 编译器转换为:a.intValue()

// 运算时的自动拆箱
Integer x = 10;
Integer y = 20;
Integer z = x + y;  // 先拆箱:x.intValue() + y.intValue(),再装箱
Integer缓存机制(重要!)
Integer a = 100;
Integer b = 100;
Integer c = 200;
Integer d = 200;

System.out.println(a == b);  // true,-128~127之间有缓存
System.out.println(c == d);  // false,超出缓存范围

// 源码分析:
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
// 默认缓存范围:-128 ~ 127
自动装箱的性能问题
// 不推荐的写法:频繁创建Integer对象
Long start = System.currentTimeMillis();
Integer sum = 0;  // 这里发生了自动装箱
for (int i = 0; i < 1000000; i++) {
    sum += i;  // 这里发生了:拆箱 → 相加 → 装箱
}
Long end = System.currentTimeMillis();
System.out.println("耗时:" + (end - start) + "ms");

// 推荐的写法:使用基本类型
long start2 = System.currentTimeMillis();
int sum2 = 0;  // 基本类型,在栈中分配
for (int i = 0; i < 1000000; i++) {
    sum2 += i;  // 直接运算
}
long end2 = System.currentTimeMillis();
System.out.println("耗时:" + (end2 - start2) + "ms");

自动装箱的最佳实践:

  1. 循环体内避免使用包装类型

  2. 集合框架必须使用包装类型

  3. 数据库查询结果可能为null时使用包装类型

  4. 方法参数允许null值时使用包装类型


三、字符串类

3.1 String类 - 不可变字符串

String的特点
// 1. final类,不可被继承
// 2. 使用final char[]存储,不可修改
// 3. 实现了Serializable、Comparable、CharSequence接口

// 不可变性示例
String str = "hello";
str.concat(" world");  // 创建新对象,原str不变
System.out.println(str);  // 输出:hello

String newStr = str.concat(" world");
System.out.println(newStr);  // 输出:hello world
字符串的创建方式
// 方式1:字面量(推荐)
String s1 = "hello";  // 在常量池中创建
String s2 = "hello";  // 复用常量池中的"hello"

// 方式2:new关键字
String s3 = new String("hello");  // 在堆中创建新对象
String s4 = new String("hello");  // 在堆中创建另一个新对象

// 方式3:字符数组
char[] chars = {'h', 'e', 'l', 'l', 'o'};
String s5 = new String(chars);

// 方式4:字节数组
byte[] bytes = {104, 101, 108, 108, 111};
String s6 = new String(bytes, StandardCharsets.UTF_8);

内存结构分析:

String s1 = "abc";              // 常量池
String s2 = new String("abc");  // 堆内存
String s3 = s2.intern();        // 返回常量池引用

System.out.println(s1 == s2);    // false
System.out.println(s1 == s3);    // true
System.out.println(s1.equals(s2)); // true
String的常用方法

1. 字符串获取和判断

String str = "Hello World";

// 获取长度
int length = str.length();  // 11

// 获取字符
char ch = str.charAt(1);    // 'e'

// 获取索引
int index1 = str.indexOf('o');      // 4
int index2 = str.lastIndexOf('o'); // 7
int index3 = str.indexOf("World");  // 6

// 判断
boolean b1 = str.startsWith("Hello");  // true
boolean b2 = str.endsWith("World");    // true
boolean b3 = str.contains("lo");       // true
boolean b4 = str.isEmpty();            // false
boolean b5 = "".isEmpty();             // true

2. 字符串转换

String str = "  Hello Java  ";

// 大小写转换
String upper = str.toUpperCase();  // "  HELLO JAVA  "
String lower = str.toLowerCase();  // "  hello java  "

// 去除空格
String trim = str.trim();          // "Hello Java"

// 转字符数组
char[] chars = str.toCharArray();

// 字符串分割
String[] parts = "a,b,c,d".split(",");  // ["a", "b", "c", "d"]

// 子字符串
String sub1 = str.substring(2);     // "Hello Java  "
String sub2 = str.substring(2, 7); // "Hello"

3. 字符串替换

String str = "Hello World";

// 替换字符
String s1 = str.replace('l', 'L');  // "HeLLo WorLd"

// 替换字符串
String s2 = str.replace("World", "Java");  // "Hello Java"

// 正则替换
String s3 = "a1b2c3".replaceAll("\\d", "*");  // "a*b*c*"
String s4 = "a1b2c3".replaceFirst("\\d", "*"); // "a*b2c3"

4. 字符串比较

String s1 = "hello";
String s2 = "HELLO";
String s3 = "hello";
String s4 = "hell";

// equals - 区分大小写
System.out.println(s1.equals(s2));  // false

// equalsIgnoreCase - 忽略大小写
System.out.println(s1.equalsIgnoreCase(s2));  // true

// compareTo - 字典序比较
System.out.println(s1.compareTo(s3));  // 0
System.out.println(s1.compareTo(s4));  // 1
System.out.println(s4.compareTo(s1));  // -1

3.2 StringBuffer - 可变字符串(线程安全)

StringBuffer的特点
// 1. 线程安全的可变字符序列
// 2. 内部使用char[]存储,可动态扩容
// 3. 方法使用synchronized修饰,保证线程安全
构造方法
// 默认构造:初始容量16
StringBuffer sb1 = new StringBuffer();

// 指定初始容量
StringBuffer sb2 = new StringBuffer(100);

// 通过字符串创建
StringBuffer sb3 = new StringBuffer("Hello");
常用方法
StringBuffer sb = new StringBuffer("Hello");

// 追加
sb.append(" World");       // "Hello World"
sb.append(123);            // "Hello World123"
sb.append(true);           // "Hello World123true"

// 插入
sb.insert(5, ",");         // "Hello, World123true"

// 删除
sb.delete(5, 6);           // "Hello World123true"
sb.deleteCharAt(5);         // "Hello orld123true"

// 替换
sb.replace(6, 11, "Java"); // "Hello Java123true"

// 反转
sb.reverse();               // "eurt321avaJ olleH"

// 容量相关
int capacity = sb.capacity();  // 当前容量
sb.ensureCapacity(100);       // 确保最小容量
sb.trimToSize();              // 修剪到实际长度

// 转String
String result = sb.toString();

3.3 StringBuilder - 可变字符串(非线程安全)

StringBuilder vs StringBuffer
// 1. StringBuilder非线程安全,性能更高
// 2. StringBuffer线程安全,性能稍低
// 3. API完全兼容

// 性能对比示例
long start = System.currentTimeMillis();
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < 100000; i++) {
    buffer.append(i);
}
long bufferTime = System.currentTimeMillis() - start;

start = System.currentTimeMillis();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 100000; i++) {
    builder.append(i);
}
long builderTime = System.currentTimeMillis() - start;

System.out.println("StringBuffer: " + bufferTime + "ms");
System.out.println("StringBuilder: " + builderTime + "ms");

3.4 字符串拼接性能对比

// 方式1:+ 拼接(少量时可用)
String s1 = "a" + "b" + "c";  // 编译器优化为"abc"

// 方式2:concat方法
String s2 = "a".concat("b").concat("c");

// 方式3:StringBuilder(单线程推荐)
StringBuilder sb = new StringBuilder();
sb.append("a").append("b").append("c");
String s3 = sb.toString();

// 方式4:StringBuffer(多线程环境)
StringBuffer sbf = new StringBuffer();
sbf.append("a").append("b").append("c");
String s4 = sbf.toString();

// 方式5:String.join(Java 8+)
String s5 = String.join("", "a", "b", "c");

性能测试结果(拼接10000次):

  • 使用+:最慢,每次拼接创建新对象

  • 使用concat:较慢

  • 使用StringBuilder:最快

  • 使用StringBuffer:次快(有同步开销)


四、日期时间类

4.1 System类的时间方法

// 1. 当前时间戳(毫秒)
long timestamp = System.currentTimeMillis();
System.out.println("时间戳:" + timestamp);

// 2. 当前时间戳(纳秒,用于高精度计时)
long nanoTime = System.nanoTime();
System.out.println("纳秒时间:" + nanoTime);

// 3. 计算程序运行时间
long start = System.currentTimeMillis();
// ... 执行代码 ...
long end = System.currentTimeMillis();
System.out.println("执行时间:" + (end - start) + "ms");

// 4. 系统属性
String osName = System.getProperty("os.name");
String javaVersion = System.getProperty("java.version");
System.out.println("操作系统:" + osName);
System.out.println("Java版本:" + javaVersion);

4.2 Date类(已过时,了解即可)

// 创建Date对象
Date now = new Date();  // 当前时间
System.out.println(now);  // 输出:Mon Jan 17 10:30:00 CST 2023

// 指定时间创建
Date specificDate = new Date(1234567890000L);
System.out.println(specificDate);

// 获取时间戳
long time = now.getTime();  // 毫秒数
System.out.println(time);

// 设置时间
now.setTime(1234567890000L);

4.3 Calendar类(传统日期处理)

// 获取Calendar实例
Calendar calendar = Calendar.getInstance();

// 获取日期各部分
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH) + 1;  // 月份从0开始
int day = calendar.get(Calendar.DAY_OF_MONTH);
int hour = calendar.get(Calendar.HOUR_OF_DAY);
int minute = calendar.get(Calendar.MINUTE);
int second = calendar.get(Calendar.SECOND);
int week = calendar.get(Calendar.DAY_OF_WEEK);  // 周日=1,周一=2...

// 设置日期
calendar.set(2023, Calendar.JANUARY, 1, 0, 0, 0);

// 日期计算
calendar.add(Calendar.DAY_OF_MONTH, 10);  // 10天后
calendar.add(Calendar.MONTH, -1);         // 1月前

// 比较日期
Calendar cal1 = Calendar.getInstance();
Calendar cal2 = Calendar.getInstance();
cal2.add(Calendar.DAY_OF_MONTH, 1);

boolean isBefore = cal1.before(cal2);  // true
boolean isAfter = cal1.after(cal2);    // false
boolean isEqual = cal1.equals(cal2);   // false

4.4 SimpleDateFormat(日期格式化)

// 创建格式化对象
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

// Date -> String
Date now = new Date();
String formatted = sdf.format(now);
System.out.println(formatted);  // 2023-01-17 10:30:00

// String -> Date
try {
    String dateStr = "2023-01-17 10:30:00";
    Date date = sdf.parse(dateStr);
    System.out.println(date);
} catch (ParseException e) {
    e.printStackTrace();
}

// 常用模式字母
/**
 * yyyy - 年
 * MM   - 月
 * dd   - 日
 * HH   - 时(24小时制)
 * hh   - 时(12小时制)
 * mm   - 分
 * ss   - 秒
 * SSS  - 毫秒
 * E    - 星期
 * a    - 上午/下午
 */

注意:SimpleDateFormat线程不安全

// 错误用法:多线程共享同一个SimpleDateFormat
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

// 正确用法1:每个线程创建自己的实例
// 正确用法2:使用ThreadLocal
// 正确用法3:使用Java 8的DateTimeFormatter

4.5 Java 8新的日期时间API(推荐)

// 1. LocalDate - 日期
LocalDate today = LocalDate.now();
LocalDate specificDate = LocalDate.of(2023, 1, 17);
System.out.println("今天:" + today);
System.out.println("指定日期:" + specificDate);

// 2. LocalTime - 时间
LocalTime nowTime = LocalTime.now();
LocalTime specificTime = LocalTime.of(10, 30, 0);
System.out.println("现在时间:" + nowTime);
System.out.println("指定时间:" + specificTime);

// 3. LocalDateTime - 日期时间
LocalDateTime dateTime = LocalDateTime.now();
System.out.println("当前日期时间:" + dateTime);

// 4. DateTimeFormatter - 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = dateTime.format(formatter);
System.out.println("格式化:" + formatted);

// 5. 日期计算
LocalDate tomorrow = today.plusDays(1);
LocalDate lastMonth = today.minusMonths(1);
System.out.println("明天:" + tomorrow);
System.out.println("上个月:" + lastMonth);

// 6. 日期比较
boolean isBefore = today.isBefore(tomorrow);
boolean isAfter = today.isAfter(lastMonth);
System.out.println("今天在明天之前:" + isBefore);
System.out.println("今天在上个月之后:" + isAfter);

五、Arrays类 - 数组工具类

5.1 数组的创建和初始化

// 声明数组
int[] arr1;  // 推荐
int arr2[];  // 不推荐

// 创建数组
int[] arr3 = new int[5];  // 长度为5,默认值0
int[] arr4 = {1, 2, 3, 4, 5};  // 初始化
int[] arr5 = new int[]{1, 2, 3, 4, 5};

5.2 Arrays常用方法

1. 数组转字符串
int[] arr = {1, 2, 3, 4, 5};
String str = Arrays.toString(arr);
System.out.println(str);  // [1, 2, 3, 4, 5]

// 深度toString(用于多维数组)
int[][] deepArr = {{1, 2}, {3, 4}};
String deepStr = Arrays.deepToString(deepArr);
System.out.println(deepStr);  // [[1, 2], [3, 4]]
2. 数组排序
int[] arr = {5, 3, 1, 4, 2};

// 默认排序(升序)
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));  // [1, 2, 3, 4, 5]

// 部分排序
int[] arr2 = {5, 3, 1, 4, 2, 6, 8, 7};
Arrays.sort(arr2, 2, 6);  // 排序索引[2,6)的元素
System.out.println(Arrays.toString(arr2));  // [5, 3, 1, 2, 4, 6, 8, 7]

// 自定义排序
Integer[] arr3 = {5, 3, 1, 4, 2};
Arrays.sort(arr3, (a, b) -> b - a);  // 降序
System.out.println(Arrays.toString(arr3));  // [5, 4, 3, 2, 1]
3. 数组查找
int[] arr = {1, 3, 5, 7, 9};

// 二分查找(必须先排序)
int index = Arrays.binarySearch(arr, 5);
System.out.println("5的索引:" + index);  // 2

// 查找不存在的元素
int index2 = Arrays.binarySearch(arr, 6);
System.out.println("6的索引:" + index2);  // 负数,表示插入点
4. 数组比较
int[] arr1 = {1, 2, 3};
int[] arr2 = {1, 2, 3};
int[] arr3 = {1, 2, 4};

// equals - 比较一维数组
boolean eq1 = Arrays.equals(arr1, arr2);  // true
boolean eq2 = Arrays.equals(arr1, arr3);  // false

// deepEquals - 比较多维数组
int[][] deepArr1 = {{1, 2}, {3, 4}};
int[][] deepArr2 = {{1, 2}, {3, 4}};
boolean deepEq = Arrays.deepEquals(deepArr1, deepArr2);  // true
5. 数组填充
int[] arr = new int[5];

// 全部填充
Arrays.fill(arr, 1);
System.out.println(Arrays.toString(arr));  // [1, 1, 1, 1, 1]

// 部分填充
Arrays.fill(arr, 1, 4, 2);
System.out.println(Arrays.toString(arr));  // [1, 2, 2, 2, 1]
6. 数组复制
int[] original = {1, 2, 3, 4, 5};

// copyOf - 指定长度
int[] copy1 = Arrays.copyOf(original, 3);
System.out.println(Arrays.toString(copy1));  // [1, 2, 3]

int[] copy2 = Arrays.copyOf(original, 7);
System.out.println(Arrays.toString(copy2));  // [1, 2, 3, 4, 5, 0, 0]

// copyOfRange - 指定范围
int[] copy3 = Arrays.copyOfRange(original, 1, 4);
System.out.println(Arrays.toString(copy3));  // [2, 3, 4]
7. 数组转列表
Integer[] arr = {1, 2, 3, 4, 5};

// Arrays.asList - 返回固定大小的列表
List<Integer> list = Arrays.asList(arr);
System.out.println(list);  // [1, 2, 3, 4, 5]

// 注意:这个列表不支持添加/删除操作
// list.add(6);  // 抛出UnsupportedOperationException

// 如果要可变列表
List<Integer> mutableList = new ArrayList<>(Arrays.asList(arr));
mutableList.add(6);  // 正常
8. 并行排序(大数据量优化)
int[] largeArr = new int[1000000];
Random random = new Random();
for (int i = 0; i < largeArr.length; i++) {
    largeArr[i] = random.nextInt(1000000);
}

// 并行排序(多核CPU加速)
long start = System.currentTimeMillis();
Arrays.parallelSort(largeArr);
long time = System.currentTimeMillis() - start;
System.out.println("并行排序耗时:" + time + "ms");

// 对比普通排序
int[] largeArr2 = Arrays.copyOf(largeArr, largeArr.length);
start = System.currentTimeMillis();
Arrays.sort(largeArr2);
time = System.currentTimeMillis() - start;
System.out.println("普通排序耗时:" + time + "ms");

六、Random类 - 随机数生成

6.1 Random类的使用

创建Random对象
// 默认种子(使用当前时间毫秒数)
Random random1 = new Random();

// 指定种子(相同种子产生相同随机序列)
Random random2 = new Random(12345L);
生成随机数
Random random = new Random();

// 1. 生成int随机数
int randomInt = random.nextInt();  // 整个int范围
int boundInt = random.nextInt(100);  // [0, 100)

// 2. 生成指定范围的随机数
int min = 10, max = 20;
int rangeInt = random.nextInt(max - min) + min;  // [10, 20)

// 3. 生成long随机数
long randomLong = random.nextLong();

// 4. 生成float随机数
float randomFloat = random.nextFloat();  // [0.0, 1.0)

// 5. 生成double随机数
double randomDouble = random.nextDouble();  // [0.0, 1.0)

// 6. 生成boolean随机数
boolean randomBoolean = random.nextBoolean();

// 7. 生成高斯分布随机数
double gaussian = random.nextGaussian();  // 均值0,标准差1

6.2 种子(Seed)的作用

// 相同种子产生相同随机序列
Random r1 = new Random(123);
Random r2 = new Random(123);

System.out.println("r1的第一个随机数:" + r1.nextInt(100));
System.out.println("r2的第一个随机数:" + r2.nextInt(100));
System.out.println("r1的第二个随机数:" + r1.nextInt(100));
System.out.println("r2的第二个随机数:" + r2.nextInt(100));

// 输出:
// r1的第一个随机数:83
// r2的第一个随机数:83
// r1的第二个随机数:87
// r2的第二个随机数:87

6.3 ThreadLocalRandom(多线程推荐)

// 获取ThreadLocalRandom实例
ThreadLocalRandom random = ThreadLocalRandom.current();

// 生成随机数
int num1 = random.nextInt();           // 整个int范围
int num2 = random.nextInt(100);        // [0, 100)
int num3 = random.nextInt(10, 100);    // [10, 100)
double num4 = random.nextDouble(1.0, 10.0);  // [1.0, 10.0)

ThreadLocalRandom的优势:

  1. 每个线程有自己的随机数生成器

  2. 避免多线程竞争,提高性能

  3. API更简洁,支持范围生成

6.4 SecureRandom(安全随机数)

// 用于加密的安全随机数
SecureRandom secureRandom = new SecureRandom();

// 生成随机字节
byte[] bytes = new byte[16];
secureRandom.nextBytes(bytes);

// 生成int随机数
int secureInt = secureRandom.nextInt();

// 设置种子
secureRandom.setSeed(System.currentTimeMillis());

SecureRandom的特点:

  1. 加密强度高,不可预测

  2. 性能比Random低

  3. 适用于密码学、安全令牌等场景


七、最佳实践总结

7.1 字符串处理

  1. 少量字符串拼接:使用+或concat

  2. 循环内字符串拼接:使用StringBuilder(单线程)或StringBuffer(多线程)

  3. 字符串比较:使用equals()比较内容,注意null检查

  4. 常量字符串:使用字面量方式创建

7.2 日期时间处理

  1. 新项目:使用Java 8的java.time包

  2. 旧项目维护:注意SimpleDateFormat的线程安全问题

  3. 时间戳:使用System.currentTimeMillis()获取毫秒时间戳

7.3 数组操作

  1. 数组转字符串:使用Arrays.toString()

  2. 数组排序:使用Arrays.sort()

  3. 大数组排序:考虑使用Arrays.parallelSort()

  4. 数组复制:使用Arrays.copyOf()或System.arraycopy()

7.4 随机数生成

  1. 一般用途:使用Random类

  2. 多线程环境:使用ThreadLocalRandom

  3. 安全相关:使用SecureRandom

  4. 指定范围:使用nextInt(max-min)+min公式

7.5 性能优化建议

  1. 避免在循环中创建对象

  2. 合理使用包装类的缓存机制

  3. 字符串操作使用StringBuilder

  4. 使用Arrays工具类替代手动操作

  5. 日期格式化使用线程安全的方式


通过本文的详细解析,你应该对Java常用类有了全面的了解。这些类是Java编程的基础,掌握它们的特性和使用场景,能够帮助你编写出更高效、更健壮的代码。在实际开发中,根据具体需求选择合适的类和方法,是成为Java高手的重要一步。

YOLO系列训练时出现loss出现nan值或者测试时P\R\map全部为0值的解决办法(GTX16xx系列显卡大坑) 阅读详情

相关推荐

SPSS实战:如何用Harman单因素检验搞定共同方法偏差(附完整操作步骤)

本文提供了一份详尽的SPSS实战指南,手把手教你运用Harman单因素检验来诊断共同方法偏差。文章从核心概念讲起,逐步详解数据准备、SPSS操作步骤、结果解读与报告撰写,帮助研究者快速掌握这一关键的数据质量控制方法,确保量化研究结论的可靠性。

weixin_29263201的博客 1694

Java类和对象详解:从图纸到实例,一次搞懂构造器、内存与实战

Java作为面向对象编程的主流语言,其核心抽象都建立在类与对象之上。类相当于设计图纸,对象是根据图纸生产出的运行时实例;通过new关键字在内存中创建对象,并借助构造器完成初始化,是每个开发者必须建立的底层直觉。理解这一机制,不仅能解决“为什么对象比较要用equals而不用==”之类的常见困惑,也能为封装、抽象类、深拷贝、垃圾回收乃至类加载机制打下基础。在真实开发中,无论是学生成绩管理、订单处理还是Spring框架的Bean管理,都是把现实实体抽象为对象后进行统一操作的工程实践。本文用通俗类比和完整代码示例,

weixin_30512965的博客 325

同步辐射材料科学应用指南:从XAFS原位实验到数据处理

材料结构分析是材料研究的核心环节,但传统实验室X射线受限于能量固定、亮度不足,往往难以回答原子局域配位、非晶结构及动态演变等关键问题。同步辐射光源以高通量、连续可调、偏振可控及脉冲时间结构等特性,将材料表征从静态观察推进到原位动态追踪层次。基于X射线吸收精细结构谱(XAFS)、原位实验、X射线衍射与散射、微区成像等技术,研究人员可实现元素选择性分析、近邻原子环境解析及真实工况下的结构演变监测。本文从技术原理出发,覆盖实验方案设计、样品制备、现场对光、数据处理与常见故障排查,并结合典型应用场景,为材料科学领域

weixin_32612263的博客 161

7、Java 核心 API 与常用类库详解

本文介绍了Java核心类库体系中的字符串处理和日期时间API。字符串处理部分涵盖不可变的String、高效的StringBuilder(单线程)和线程安全的StringBuffer(多线程),强调不同场景下的选择建议。日期时间API对比了已过时的传统类(Date/Calendar)与现代Java 8+的java.time包(LocalDate/LocalDateTime等),推荐使用后者进行日期计算和格式化。示例代码演示了各类的核心操作,包括字符串拼接、日期计算和格式化输出,帮助开发者掌握这些基础但重要的A

python15397的博客 546

音频测试专题

麦克风与扬声器单体测试指标及整机性能测试概述 麦克风测试指标包括频率响应、灵敏度、指向性等10项关键参数,用于评估声音捕捉和信号转换性能。扬声器测试包含频率响应、灵敏度等12项指标,涉及声学特性和物理参数。整机性能测试覆盖安静、嘈杂和正常三种环境,重点检测麦克风底噪、清晰度、扬声器音量及通话质量等12项功能指标。两类单体测试与整机测试共同构成完整的音频设备质量评估体系,确保产品在不同场景下的性能表现。

weixin_52640906的博客 1315

英飞凌 TC4X MCAL之SPI中断与DMA高效传输实战

本文详细介绍了英飞凌TC4X芯片的SPI通信实战,重点讲解如何通过MCAL配置SPI中断与DMA实现高效数据传输。针对汽车电子领域的高吞吐需求,提供了从基础配置到中断处理、DMA优化的完整解决方案,包含代码示例和调试技巧,帮助开发者提升系统性能与CPU利用率。

k0l1m2n3o的博客 874

java常用类及接口

1.1 java API类库Java运行环境 (Java Runtime Environment,JRE)为一般的应用开发提供了大量类库支持,其提供的基础类库被称为JFC。这些系统定义好的类根据实现的功能不同,可以划分成不同的集合,每个集合是一个包,合称类库。java类库主要有以下几种:java.lang Java语言的核心类库,定义了Java中的Object、String、Boolean、Byte

在黑夜中前行 1607

用PyCharm+Scrapy打造你的第一个爬虫:从安装到实战(附完整代码)

本文详细介绍了如何使用PyCharm和Scrapy框架从零开始构建高效网络爬虫。通过环境配置、项目创建、核心爬虫逻辑编写到数据处理与存储的完整流程,帮助Python开发者快速掌握爬虫开发技巧,并附有实战代码示例。特别适合想要学习Scrapy框架和提升爬虫技能的开发者。

weixin_29038345的博客 868

深入探讨java常用类-------Object、Math、Random与日期时间类(上)

类是Java中的顶级父类,所有类都直接或间接继承自它。即使在没有显式继承其他类的情况下,一个类也默认继承自Object类。Object类提供了一些基本的方法,这些方法在所有Java对象中都可用。本文重点介绍Object:返回对象的字符串表示形式。:判断两个对象是否“相等”。:创建并返回对象的副本。:当对象被垃圾回收时调用。Math类提供了基本的数学运算方法,如指数、对数、平方根和三角函数等。所有Math类中的方法都是静态的,无需创建对象即可调用。Random类用于生成伪随机数流。

huhuhu667的博客 712

2022年全国职业院校技能大赛高职组大数据技术与应用赛项赛卷⑩—解析答案

工业互联网是工业全要素、全产业链、全价值链的全面连接,是人、机、物、工厂互联互通的新型工业生产制造服务体系,是互联网从消费领域向生产领域、从虚拟经济向实体经济拓展的核心载体,是建设现代化经济体系、实现高质量发展和塑造全球产业竞争力的关键支撑。加快发展工业互联网产业,不仅是各国顺应产业发展大势,抢占产业未来制高点的战略选择,也是我国推动制造业质量变革、效率变革和动力变革,实现高质量发展的客观要求。 为完成工业大数据分析工作,你所在的小组将应用大数据技术,以Scala作为整个项目的基础开发语言,基于大数据平台综

我是网络安全兼技能大赛工程师,专注网络安全技术学习与技能大赛实战!持续分享最新的技术文章,帮你少走弯路,一起在技术赛道上进步~ 579

YOLOv8改进 | 主干篇 | 利用MobileNetV1替换Backbone(轻量化网络结构)

本文给大家带来的改进机制是MobileNetV1,其是专为移动和嵌入式视觉应用设计的轻量化网络结构。这些模型基于简化的架构,并利用深度可分离卷积构建轻量级深度神经网络,其引入了两个简单的全局超参数,用于在延迟和准确性之间进行有效的权衡。实验表明,MobileNets在资源和准确性的权衡方面表现出色,并在多种应用(如对象检测、细粒度分类、面部属性识别和大规模地理定位)中展现了其有效性,这个模型非常适合轻量化的读者来使用。适用检测目标:轻量化网络结构适合轻量化的读者。

Snu77的博客 3966

API——常用类

目录 1. API概述 2. 常用类 2.1 Object类/Scanner类 2.1.1 Object类概述及构造方法 2.1.2 Object类的成员方法 2.1.3 Scanner类概述及其构造方法 2.1.4 Scanner类的成员方法 2.2 String类/StringBuffer类/StringBuilder类 2.2.1 String类概述及其构造方法 2.2....

afsf12134的博客 848

ATECC508A芯片开发笔记(四):自定义配置508功能,规划DataZone数据存储

ATECC508A芯片开发笔记(四):自定义配置508功能,规划DataZone数据存储 508A内部存储区介绍 Data Zone Config Zone 508A Config Zone配置(自定义) - ATECC508A芯片在使用之前,需要自定义配置ConfigZone与DataZone,并同Lock命令将两个区域锁住,否则无法正常使用功能。而一旦锁上就是永久性的,配置区不能够进行解锁

HowieXue 薛永浩的博客 2万+

Java面向对象 - 常用类

简介 本实训项目的主要内容是介绍 Java 类库所提供的常用类及类的常用方法, Java 中常用的类有: Object类; Java 基础类型包装类; String&StringBuilder&StringBuffer类; Random类; Date类; SimpleDateFormat类; Math类。 在前面的实训中,我们已经学习了 Java 基础类型包装类和String类,接下来我们将学习其他 4 种 Java 常

aiains的博客 2095

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

第3章-第3节-Java核心类库之Scanner和Random

第3章-第3节-Java核心类库之Scanner和Random

Zwarwolf的专栏 532

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

第十一章 Java常用类

Java基础

richieandndsc的博客 500

【Java】基础14:Scanner类、Random类、ArrayList类

随机抽奖就是这么来的?

刘小爱的博客 657

Java常用类

Java常用类

qq_45677189的博客 472

java 常用类总结

Object类 String类/StringBuffer类/StringBuilder类 数组高级和Arrays类 基本类型包装类(Integer) 正则表达式(Pattern,Matcher) Math类/Random类/System类 Date类/DateFormat类/Calendar类

saint_la的博客 509

java常用的io类_Java常用类、集合、IO-简单版

目录Java常用类、集合、IO常用类ObjectMathRandomFile包装类DataStringStringBufferStringBuilder集合框架CollectionList(有序可重复)ArrayList数组 (常用)LinkedList链表 (常用)VectorStackSet(无序不可重复)HashSet(常用)TreeSetIterator迭代器MapHashMap(重点,天...

weixin_42509624的博客 442

包 java中导入awt_JAVA应用程序开发之常用类库

【本文详细介绍了JAVA应用开发中的常用类库,欢迎读者朋友们阅读、转发和收藏!】1 基本概念Java 类库是 JAVA API ( Application Progaramming Interface ,应用程序接口),在 Java 系统中,系统定义好的类根据实现的功能不同,可以划分成不同的集合。每个集合称为一个包,所有包合称为类库。在程序设计中,合理和充分利用类库提供的类和接口,不仅可以完成字符...

weixin_29818013的博客 1650

小饶学编程之JAVA SE第一部分——JavaSE 核心类库:12常用类(二):Sring、正则、StringBuffer、StringBuilder、Math、Random、Date

String和正则一、String常用方法二、正则2.1概念2.2规则2.3用法三、StringBuffer和StringBuilder3.1区别四.Math和Random1.Math常用方法2.Random常用方法五.日期类1.Date2.Calendar3.SimpleDateFormat 一、String常用方法 长度 length() 拼接 str.concat(str2) 格式化 //方式一 System.out.printf("大家好,我的名字叫:%s,我今年:%d岁了,我的存款有:%f

weixin_46460843的博客 460

java 常用类_Java常用类

System类总共包含 6 篇文章System作为系统类,在JDK的Java.lang包中,可见它也是一种java的核心语言特性。System类的构造器由private修饰,不允许被实例化。因此,类中的方法也都是static修饰的静态方法。System是最常用类之一,一定要掌握好。常用 Character类总共包含 11 篇文章Character类在对象中包装一个基本类型char的值,用于对单个字...

weixin_34005090的博客 90

Java基础知识(二十三)常用类四(Arrays,Date,Math,包装类,Random)

一、Arrays类 二、Date类 三、Math类 四、包装类 1、调用包装类的方法 2、字符串转换 五、Random类

L缶神的博客 685

第七部分:Java常用类库

本文介绍了Java常用工具类及其应用,包括:1. String类和StringBuffer类的字符串处理功能;2. 8种基本数据类型的包装类实现面向对象转换;3. System类和Runtime类提供的系统操作方法;4. Date、Calendar和DateFormat类处理日期时间;5. Math类数学运算和Random类随机数生成;6. hashCode()方法计算对象散列值;7. 对象克隆机制及Cloneable接口实现。这些工具类为Java开发提供了基础功能支持。

inferno_lucerne的博客 1010

Java SE day 14 常用类 二

常用类(二) 常用类(二)1. Random类1.1 创建Random对象1.2 Random的常用方法2. System类2.1 System类属性2.2 System类方法3. Runtime类4. Date类5. SimpleDateFormat类6. Calendar类7. 枚举8. BigInteger类和BigDecemal8.1 四舍五入 1. Random类 1.1 创建Random对象 此类用于生成随机数: 两种构造方法 1.Random(); 创建一个新的随机数生成器 2

Zhangxiangyiyi的博客 210
上一篇: Java异常处理全解析:从基础到高级实战
下一篇: Java集合框架详解
StackNoOverflow
博客等级 码龄1年 22粉丝 48原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值