【小家java】聊聊Java中的java.util.Arrays类和java.util.Collections工具类(下)

简介: 【小家java】聊聊Java中的java.util.Arrays类和java.util.Collections工具类(下)

Collections工具类介绍


此类完全由在 collection 上进行操作或返回 collection 的静态方法组成

如果为此类的方法所提供的collection 或类对象为 null,则这些方法都将抛出NullPointerException。

public的可用字段摘要(都用对应的get方法供访问)


public static final List EMPTY_LIST:空的列表(不可变的)
public static final Map EMPTY_MAP:空的映射(不可变的)
public static final Set EMPTY_SET:空的 set(不可变的)


排序


集合排序,不可为使用不多,啥都不说,直接上例子,解释都放在例子里面


    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(12);
        list.add(-15);
        list.add(7);
        list.add(4);
        list.add(35);
        list.add(9);
        System.out.println("源列表:" + list); //[12, -15, 7, 4, 35, 9]
        // 排序(自然顺序)
        Collections.sort(list);
        System.out.println("自然序:" + list); //[-15, 4, 7, 9, 12, 35]
        // 逆序
        Collections.reverse(list);
        System.out.println("逆序:" + list); //[35, 12, 9, 7, 4, -15]
        // 随机排序(扑克牌洗牌经常使用) 每次结果都不一样
        Collections.shuffle(list);
        System.out.println("随机序:" + list); //[9, 4, -15, 12, 7, 35]
        // 定制排序的用法(根据指定比较器产生的顺序对指定列表进行排序),将int类型转成string进行比较(注意,不再是数字了,排序有变化)
        Collections.sort(list, Comparator.comparing(String::valueOf));
        System.out.println("定制序:" + list); //[-15, 12, 35, 4, 7, 9]
        // 旋转(旋转效果有点意思)
        Collections.rotate(list, 3); //[4, 7, 9, -15, 12, 35]
        System.out.println("旋转3:" + list);
        Collections.rotate(list, -3);
        System.out.println("旋转-3:" + list); //[-15, 12, 35, 4, 7, 9]
    }


对比下结果:

image.png


swap 交换两个位置的值


//list-- 在该列表中的调剂元素。
//i-- 要交换的一个元素的索引。
//j-- 要交换的其它元素的索引。
// 请注意i/j都不要超出范围
public static void swap(List<?> list,int i,int j);


案例:


    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(12);
        list.add(-15);
        list.add(7);
        list.add(4);
        list.add(35);
        list.add(9);
        System.out.println("swap之前:" + list);
        Collections.swap(list, 0, 2); //把0位置元素和2位置交换(备注:若是不可变集合,此处是会抛错的)
        System.out.println("swap之后:" + list);
    }


查找及替换操作


   public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(12);
        list.add(-15);
        list.add(7);
        list.add(4);
        list.add(35);
        list.add(9);
        System.out.println("源列表:" + list);
        // 最大值
        System.out.println("最大值:" + Collections.max(list)); //35
        // 最小值
        System.out.println("最小值:" + Collections.min(list)); //-15
        // 替换 把所有的-15替换成12
        Collections.replaceAll(list, -15, 12);
        System.out.println("-15替换12:" + list); //[12, 12, 7, 4, 35, 9]
        // 出现次数(这个特别有用  某个元素出现的此处)  支持找null出现的次数哦~~~~
        System.out.println("12出现次数:" + Collections.frequency(list, 12)); //2
        // 排序  因为二分查找必须有序  否则可能不准
        Collections.sort(list);
        System.out.println("排序后:" + list); //[4, 7, 9, 12, 12, 35]
        // 二分查找 (注意,返回的是查找对象的索引,List必须是有序的)
        System.out.println("-15下标:" + Collections.binarySearch(list, -15)); //-1 没找到就是-1
        System.out.println("7下标:" + Collections.binarySearch(list, 7)); //1
        System.out.println("35下标:" + Collections.binarySearch(list, 35)); //5
        //indexOfSubList:返回指定源列表中第一次出现指定目标列表的起始位置;如果没有出现这样的列表,则返回-1。
        //lastIndexOfSubList:同上 (最后一次)   若出现多次的请,会有差异
        System.out.println(Collections.indexOfSubList(list, Arrays.asList(7, 9))); //1
        System.out.println(Collections.lastIndexOfSubList(list, Arrays.asList(7, 9))); //1
        //fill:用后面元素,把所有元素都给替换掉
        Collections.fill(list, 1);
        System.out.println("fill后的:" + list); //[1, 1, 1, 1, 1, 1]
    }


同步和只读


这个使用起来比较简单,但是能提高效率和安全性。特别是只读的,建议大家多使用

SynchronizedList(), SynchronizedSet(),unmodifiableCollection等等


singletonXXX

    public static <T> Set<T> singleton(T o) {
        return new SingletonSet<>(o);
    }
    public static <T> List<T> singletonList(T o) {
        return new SingletonList<>(o);
    }
    public static <K,V> Map<K,V> singletonMap(K key, V value) {
        return new SingletonMap<>(key, value);
    }


以前我们要初始化一个元素,到List,我们经常这么用:Arrays.asList(),那么今后,若只有一个元素需要构建list,请使用singletonXXX吧~~~


singletonXXX优势分析:

这个方法主要用于只有一个元素的优化,减少内存分配,无需分配额外的内存,可以从SingletonList内部类看得出来,由于只有一个element,因此可以做到内存分配最小化,相比之下ArrayList的DEFAULT_CAPACITY=10个


同样需要注意的是:他们返回都是只读的List,如果调用修改接口,将会抛出UnsupportedOperationException


其它


   addAll(Collection<? super T> c, T… elements):将所有指定元素添加到指定collection 中


   copy(List<? super T> dest, List<? extends T> src):将所有元素从一个列表复制到另一个列表(挺好用)


   disjoint(Collection<?> c1, Collection<?> c2):如果两个指定collection 中没有相同的元素,则返回 true (判断两个集合是否有重合的元素) 建议使用,毕竟JDK的算法还不错


   nCopies(int n, T o):返回由指定对象的n 个副本组成的不可变列表 (可以copy)


    public static void main(String[] args) {
        //若需要生成相同元素,可用这个快速生成
        List<Integer> list = Collections.nCopies(5, new Integer(1));
        System.out.println(list); //[1, 1, 1, 1, 1]
        //注意,这里返回true,所以需要注意:长度虽然是5  但是都是副本的拷贝,变一个其余都变的
        System.out.println(list.size());
        System.out.println(list.get(0) == list.get(1)); //true
    }


     asLifoQueue(Deque deque):以后进先出(Lifo) Queue 的形式返回某个 Deque 的视图

Deque是接口,具体继承关系为:Collection–>Queue–>Deque–>LinkedList、ArrayDeque、LinkedBlockingDeque


**Queue(队列)接口与List、Set同一级别,都是继承了Collection接口。Queue使用时要尽量避免Collection的add()和remove()方法,而是要使用offer()来加入元素,使用poll()来获取并移出元素。**它们的优点是通过返回值可以判断成功与否,add()和remove()方法在失败的时候会抛出异常。 如果要使用前端而不移出该元素,使用element()或者peek()方法。


Deque(双端队列)接口支持两端插入和移除元素。名称deque 是“double ended queue(双端队列)”的缩写,通常读为“deck”。


    public static void main(String[] args) {
        //LinkedList 是先进先出的First-in-first-out fifo
        LinkedList<Integer> llist1 = new LinkedList<>(Arrays.asList(2, 4, 6));
        System.out.println(llist1); //[2, 4, 6]
        //offer方法底层调用add方法,一模一样的
        System.out.println(llist1.add(5)); //true 添加成功返回的true
        System.out.println(llist1); //[2, 4, 6, 5]  发现添加到尾部的
        //element和peek都是把队列首部元素取出  但是不移除   poll()方法也是取出,但是会移除
        System.out.println(llist1.element()); //2
        System.out.println(llist1.peek()); //2
        System.out.println(llist1); //[2, 4, 6, 5, 9]
        System.out.println("-------------------------");
        //变成Last-in-first-out  lifo的队列  也就是后进先出(上面LinkedList是先进先出,需要注意)
        Queue q = Collections.asLifoQueue(llist1);
        System.out.println(q);
        System.out.println(q.add(5)); //true
        System.out.println(q); //[5, 2, 4, 6, 5]
    }


  • checkedCollection、checkedList等等:返回类型检查的集合,更安全了。(备注:现在都使用泛型集合了,不太建议使用了。当然MyBatis里存在一些问题,可以考虑使用)


    public static void main(String[] args) {
        //这样子,下面程序不抱错,显然是纯在安全隐患的
        //List<String> list = Arrays.asList("12","23");
        //List obj = list;
        list中存在了一个非String类型,程序执行到这里不会报错
        //obj.add(112);
        List<String> list = Arrays.asList("12", "23");
        List<String> safeList = Collections.checkedList(list, String.class);
        List obj = safeList;
        //检查容器视图受限于虚拟机可运行的运行时检查   这里就报错了
        obj.add(new Date());//只有执行到这一步才会抛出java.lang.ClassCastException
    }


总结


ArryasCollections是JDK提供给我们的非常好用的两个工具类。工欲善其事必先利其器,掌握了更多的好用工具,我们才能事半功倍

相关文章
|
5天前
|
Java 编译器 ice
【Java开发指南 | 第十五篇】Java Character 类、String 类
【Java开发指南 | 第十五篇】Java Character 类、String 类
24 1
|
3天前
|
自然语言处理 Java API
Java 8的Stream API和Optional类:概念与实战应用
【5月更文挑战第17天】Java 8引入了许多重要的新特性,其中Stream API和Optional类是最引人注目的两个。这些特性不仅简化了集合操作,还提供了更好的方式来处理可能为空的情况,从而提高了代码的健壮性和可读性。
26 7
|
5天前
|
Java
【Java开发指南 | 第十四篇】Java Number类及Math类
【Java开发指南 | 第十四篇】Java Number类及Math类
16 1
|
1天前
|
安全 Java 容器
Java一分钟之-并发编程:线程安全的集合类
【5月更文挑战第19天】Java提供线程安全集合类以解决并发环境中的数据一致性问题。例如,Vector是线程安全但效率低;可以使用Collections.synchronizedXxx将ArrayList或HashMap同步;ConcurrentHashMap是高效线程安全的映射;CopyOnWriteArrayList和CopyOnWriteArraySet适合读多写少场景;LinkedBlockingQueue是生产者-消费者模型中的线程安全队列。注意,过度同步可能影响性能,应尽量减少共享状态并利用并发工具类。
15 2
|
3天前
|
设计模式 算法 Java
Java的前景如何,好不好自学?,万字Java技术类校招面试题汇总
Java的前景如何,好不好自学?,万字Java技术类校招面试题汇总
|
5天前
|
安全 Java 开发者
Java一分钟之-文件与目录操作:Path与Files类
【5月更文挑战第13天】Java 7 引入`java.nio.file`包,`Path`和`Files`类提供文件和目录操作。`Path`表示路径,不可变。`Files`包含静态方法,支持创建、删除、读写文件和目录。常见问题包括:忽略异常处理、路径解析错误和权限问题。在使用时,注意异常处理、正确格式化路径和考虑权限,以保证代码稳定和安全。结合具体需求,这些方法将使文件操作更高效。
11 2
|
5天前
|
安全 Java 开发者
Java一分钟之-Optional类:优雅处理null值
【5月更文挑战第13天】Java 8的`Optional`类旨在减少`NullPointerException`,提供优雅的空值处理。本文介绍`Optional`的基本用法、创建、常见操作,以及如何避免错误,如直接调用`get()`、误用`if (optional != null)`检查和过度使用`Optional`。正确使用`Optional`能提高代码可读性和健壮性,建议结合实际场景灵活应用。
22 3
|
5天前
|
存储 Java 索引
【Java开发指南 | 第十六篇】Java数组及Arrays类
【Java开发指南 | 第十六篇】Java数组及Arrays类
10 3
|
5天前
|
存储 缓存 Java
【Java开发指南 | 第六篇】Java成员变量(实例变量)、 类变量(静态变量)
【Java开发指南 | 第六篇】Java成员变量(实例变量)、 类变量(静态变量)
12 2
|
5天前
|
Java 编译器
【Java开发指南 | 第一篇】类、对象基础概念及Java特征
【Java开发指南 | 第一篇】类、对象基础概念及Java特征
11 4