【小家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提供给我们的非常好用的两个工具类。工欲善其事必先利其器,掌握了更多的好用工具,我们才能事半功倍

相关文章
|
1月前
|
Java 开发者
在 Java 中,一个类可以实现多个接口吗?
这是 Java 面向对象编程的一个重要特性,它提供了极大的灵活性和扩展性。
148 57
|
4天前
|
JSON Java Apache
Java基础-常用API-Object类
继承是面向对象编程的重要特性,允许从已有类派生新类。Java采用单继承机制,默认所有类继承自Object类。Object类提供了多个常用方法,如`clone()`用于复制对象,`equals()`判断对象是否相等,`hashCode()`计算哈希码,`toString()`返回对象的字符串表示,`wait()`、`notify()`和`notifyAll()`用于线程同步,`finalize()`在对象被垃圾回收时调用。掌握这些方法有助于更好地理解和使用Java中的对象行为。
|
1月前
|
存储 缓存 安全
java 中操作字符串都有哪些类,它们之间有什么区别
Java中操作字符串的类主要有String、StringBuilder和StringBuffer。String是不可变的,每次操作都会生成新对象;StringBuilder和StringBuffer都是可变的,但StringBuilder是非线程安全的,而StringBuffer是线程安全的,因此性能略低。
53 8
|
1月前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
73 17
|
1月前
|
安全 Java
Java多线程集合类
本文介绍了Java中线程安全的问题及解决方案。通过示例代码展示了使用`CopyOnWriteArrayList`、`CopyOnWriteArraySet`和`ConcurrentHashMap`来解决多线程环境下集合操作的线程安全问题。这些类通过不同的机制确保了线程安全,提高了并发性能。
|
1月前
|
存储 Java 程序员
Java基础的灵魂——Object类方法详解(社招面试不踩坑)
本文介绍了Java中`Object`类的几个重要方法,包括`toString`、`equals`、`hashCode`、`finalize`、`clone`、`getClass`、`notify`和`wait`。这些方法是面试中的常考点,掌握它们有助于理解Java对象的行为和实现多线程编程。作者通过具体示例和应用场景,详细解析了每个方法的作用和重写技巧,帮助读者更好地应对面试和技术开发。
134 4
|
1月前
|
Java 编译器 开发者
Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面
本文探讨了Java异常处理的最佳实践,涵盖理解异常类体系、选择合适的异常类型、提供详细异常信息、合理使用try-catch和finally语句、使用try-with-resources、记录异常信息等方面,帮助开发者提高代码质量和程序的健壮性。
76 2
|
1月前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。
58 4
|
1月前
|
存储 Java 编译器
java wrapper是什么类
【10月更文挑战第16天】
42 3
|
1月前
|
Java Android开发
Eclipse 创建 Java 类
Eclipse 创建 Java 类
29 0