Java自带常用工具类
一、Objects:专为操作Java对象而生的工具类
1.对象判空
Objects 的 isNull 方法用于判断对象是否为空,而 nonNull 方法判断对象是否不为空。
示例代码如下:
import java.util.Objects;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Objects工具测试
 */
public class ObjectTest {
    public static void main(String[] args) {
        String name = null;
        // 输出true
        System.out.println(Objects.isNull(name));
        // 输出false
        System.out.println(Objects.nonNull(name));
    }
}
 
2.判断两个对象是否相等
我们经常需要判断两个对象是否相等,Objects 给我们提供了 equals 方法。
示例代码如下:
import java.util.Objects;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Objects工具测试
 */
public class ObjectTest {
    public static void main(String[] args) {
        String name1 = "a";
        String name2 = "A";
        // 比较两个对象是否相等 输出false
        System.out.println(Objects.equals(name1, name2));
    }
} 
如果是两个对象之间的比较,还需要重写对象的equals和hashCode方法。
我们定义一个学生类 没有实现equals方法
/**
 * @author qinxun
 * @date 2023-06-02
 * @Descripion: 学生类
 */
public class Student {
    private String name;
    private String school;
    public Student() {
    }
    public Student(String name, String school) {
        this.name = name;
        this.school = school;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSchool() {
        return school;
    }
    public void setSchool(String school) {
        this.school = school;
    }
    
} 
在测试类比较两个对象,发现两个对象并不相等
import java.util.Objects;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Objects工具测试
 */
public class ObjectTest {
    public static void main(String[] args) {
        Student student1 = new Student("qx", "桂林");
        Student student2 = new Student("qx", "桂林");
        // 比较两个对象是否相等 输出false
        System.out.println(Objects.equals(student1, student2));
    }
} 
接下来我们在实体类中实现equals方法
import java.util.Objects;
/**
 * @author qinxun
 * @date 2023-06-02
 * @Descripion: 学生类
 */
public class Student {
    private String name;
    private String school;
    public Student() {
    }
    public Student(String name, String school) {
        this.name = name;
        this.school = school;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getSchool() {
        return school;
    }
    public void setSchool(String school) {
        this.school = school;
    }
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return Objects.equals(name, student.name) && Objects.equals(school, student.school);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, school);
    }
} 
我们再次调用测试方法
import java.util.Objects;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Objects工具测试
 */
public class ObjectTest {
    public static void main(String[] args) {
        Student student1 = new Student("qx", "桂林");
        Student student2 = new Student("qx", "桂林");
        // 比较两个对象是否相等 输出true
        System.out.println(Objects.equals(student1, student2));
    }
} 
执行程序结果返回:
true 
3.对象为空时抛异常
如果我们想在对象为空时,抛出空指针异常可以使用 Objects 的 requireNonNull 方法。
示例代码如下:
import java.util.Objects;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Objects工具测试
 */
public class ObjectTest {
    public static void main(String[] args) {
        String name = null;
        System.out.println(Objects.requireNonNull(name, "名字为空"));
    }
} 
执行程序,抛出了空指针异常。
Exception in thread "main" java.lang.NullPointerException: 名字为空
	at java.util.Objects.requireNonNull(Objects.java:228)
	at demo2.ObjectTest.main(ObjectTest.java:13)
 
4.比较两个数组
deepEquals() 用于比较两个数组的对象 
import java.util.Objects;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Objects工具测试
 */
public class ObjectTest {
    public static void main(String[] args) {
        int[] array1 = {1, 2, 3};
        int[] array2 = {1, 2, 3};
        // 输出true
        System.out.println(Objects.deepEquals(array1, array2));
    }
}
 
二、Arrays:专为数组而生的工具类
1.创建数组
- copyOf:复制指定的数组,截取或用 null 填充
 - copyOfRange:复制指定范围内的数组到一个新的数组
 - fill:对数组进行填充
 
示例代码如下:
import java.util.Arrays;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: 数组工具类测试
 */
public class ArrayTest {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4};
        int[] revised = Arrays.copyOf(arr, 3);
        // 输出[1, 2, 3]
        System.out.println(Arrays.toString(revised));
        int[] expanded = Arrays.copyOf(arr, 5);
        // 输出[1, 2, 3, 4, 0]
        System.out.println(Arrays.toString(expanded));
        // 第二个参数包含,第三个参数不包含, 所以从第二位开始截取,截取到第三位
        int[] range = Arrays.copyOfRange(arr, 1, 3);
        // 输出[2, 3]
        System.out.println(Arrays.toString(range));
        
        int[] temp = new int[4];
        // 数组填充
        Arrays.fill(temp, 2);
        // 输出[2, 2, 2, 2]
        System.out.println(Arrays.toString(temp));
    }
} 
2.比较数组
Arrays 类的 equals() 方法用来判断两个数组是否相等
import java.util.Arrays;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: 数组工具类测试
 */
public class ArrayTest {
    public static void main(String[] args) {
        int[] arr = {1, 2, 3, 4};
        int[] arr1 = {2, 3, 4};
        // 输出false
        System.out.println(Arrays.equals(arr, arr1));
    }
}
 
3.数组排序
Arrays 类的 sort() 方法用来对数组进行排序
import java.util.Arrays;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: 数组工具类测试
 */
public class ArrayTest {
    public static void main(String[] args) {
        int[] arr = {3, 4, 2, 1};
        // 排序
        Arrays.sort(arr);
        // 输出[1, 2, 3, 4]
        System.out.println(Arrays.toString(arr));
    }
}
 
4.数组转Stream流
Arrays 类的 stream() 方法可以将数组转换成流
import java.util.Arrays;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: 数组工具类测试
 */
public class ArrayTest {
    public static void main(String[] args) {
        int[] arr = {3, 4, 2, 1};
        // 输出3 4 2 1 
        Arrays.stream(arr).forEach(System.out::println);
    }
}
 
5.打印数组
使用 Arrays.toString()
import java.util.Arrays;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: 数组工具类测试
 */
public class ArrayTest {
    public static void main(String[] args) {
        int[] arr = {3, 4, 2, 1};
        // 输出[3, 4, 2, 1]
        System.out.println(Arrays.toString(arr));
    }
} 
6.数组转 List
使用Arrays.asList方法
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: 数组工具类测试
 */
public class ArrayTest {
    public static void main(String[] args) {
        Integer[] arr = {3, 4, 2, 1};
        // 数组转list
        List<Integer> list = new ArrayList<>(Arrays.asList(arr));
        // 输出[3, 4, 2, 1]
        System.out.println(list);
    }
} 
三、Collections:专为集合框架而生的工具类
1.排序操作
reverse(List list):反转顺序shuffle(List list):洗牌,将顺序打乱sort(List list):自然升序sort(List list, Comparator c):按照自定义的比较器排序swap(List list, int i, int j):将 i 和 j 位置的元素交换位置
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Collections工具类测试
 */
public class CollectionTest {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("a");
        list.add("b");
        list.add("d");
        list.add("c");
        list.add("e");
        System.out.println("原始顺序:" + list);
        // 反转
        Collections.reverse(list);
        System.out.println("反转后:" + list);
        // 洗牌
        Collections.shuffle(list);
        System.out.println("洗牌后:" + list);
        // 自然升序
        Collections.sort(list);
        System.out.println("自然升序后:" + list);
        // 交换
        Collections.swap(list, 2, 4);
        System.out.println("交换后:" + list);
    }
} 
原始顺序:[a, b, d, c, e]
反转后:[e, c, d, b, a]
洗牌后:[a, e, c, b, d]
自然升序后:[a, b, c, d, e]
交换后:[a, b, e, d, c] 
2.查找操作
binarySearch(List list, Object key):二分查找法,前提是 List 已经排序过了max(Collection coll):返回最大元素max(Collection coll, Comparator comp):根据自定义比较器,返回最大元素min(Collection coll):返回最小元素min(Collection coll, Comparator comp):根据自定义比较器,返回最小元素fill(List list, Object obj):使用指定对象填充frequency(Collection c, Object o):返回指定对象出现的次数
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Collections工具类测试
 */
public class CollectionTest {
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        // 输出1
        System.out.println(Collections.binarySearch(list, 2));
        // 输出3
        System.out.println(Collections.max(list));
        // 输出1
        System.out.println(Collections.min(list));
        // 输出1
        System.out.println(Collections.frequency(list, 2));
    }
} 
3.同步控制
ArrayList 是线程不安全的,没法在多线程环境下使用,那 Collections 工具类中提供了多个 synchronizedXxx 方法,这些方法会返回一个同步的对象,从而解决多线程中访问集合时的安全问题。
我们先使用普通的ArrayList来实现多线程的数据添加
import java.util.ArrayList;
import java.util.List;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Collections工具类测试
 */
public class CollectionTest {
    public static void main(String[] args) throws InterruptedException {
        List<Integer> synchronizedList = new ArrayList<>();
        // 使用线程的方式添加两个数据到集合
        Thread thread = new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                synchronizedList.add(i);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        thread.start();
        Thread thread1 = new Thread(() -> {
            for (int i = 11; i <= 20; i++) {
                synchronizedList.add(i);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        thread1.start();
        Thread.sleep(1000);
        // 输出[1, 11, 12, 2, 13, 3, 4, 14, 5, 15, null, 16, 7, 17, 8, 18, 9, 19, 10, 20]
        System.out.println(synchronizedList);
    }
} 
我们发现不是我们需要的结果。
接下来我们使用Collections.synchronizedList方式创建可以处理多线程的集合。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Collections工具类测试
 */
public class CollectionTest {
    public static void main(String[] args) throws InterruptedException {
        List<Integer> synchronizedList = Collections.synchronizedList(new ArrayList<>());
        // 使用线程的方式添加两个数据到集合
        Thread thread = new Thread(() -> {
            for (int i = 1; i <= 10; i++) {
                synchronizedList.add(i);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        thread.start();
        Thread thread1 = new Thread(() -> {
            for (int i = 11; i <= 20; i++) {
                synchronizedList.add(i);
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }
            }
        });
        thread1.start();
        Thread.sleep(1000);
        // 输出[1, 11, 2, 12, 3, 13, 14, 4, 15, 5, 16, 6, 17, 7, 18, 8, 19, 9, 20, 10]
        System.out.println(synchronizedList);
    }
} 
实现了我们需要的结果。
4.不可变集合
emptyXxx():制造一个空的不可变集合singletonXxx():制造一个只有一个元素的不可变集合unmodifiableXxx():为指定集合制作一个不可变集合
import java.util.Collections;
import java.util.List;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Collections工具类测试
 */
public class CollectionTest {
    public static void main(String[] args) throws InterruptedException {
        List<Object> emptyList = Collections.emptyList();
        emptyList.add(3);
        System.out.println(emptyList);
    }
} 
运行程序报错
Exception in thread "main" java.lang.UnsupportedOperationException
	at java.util.AbstractList.add(AbstractList.java:148)
	at java.util.AbstractList.add(AbstractList.java:108)
	at demo2.CollectionTest.main(CollectionTest.java:16) 
5.其他
addAll(Collection<? super T> c, T... elements),往集合中添加元素disjoint(Collection<?> c1, Collection<?> c2),判断两个集合是否没有交集
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
 * @author qinxun
 * @date 2023-06-08
 * @Descripion: Collections工具类测试
 */
public class CollectionTest {
    public static void main(String[] args) throws InterruptedException {
        List<String> list = new ArrayList<>();
        Collections.addAll(list, "hello", "world");
        // 输出[hello, world]
        System.out.println(list);
        List<Integer> list1 = new ArrayList<>();
        list1.add(1);
        list1.add(2);
        List<Integer> list2 = new ArrayList<>();
        list2.add(1);
        list2.add(2);
        
        System.out.println("是否有交集:" + Collections.disjoint(list1, list2));
    }
}