Java集合框架:Arrays工具类

java.util.Arrays类能方便地操作数组,它提供的方法都是静态的。整个Arrays工具类的实现有3000+行,但是归纳总结一下可知它有以下功能(9个):


1. asList

定义:

    @SafeVarargs
    public static <T> List<T> asList(T... a) {
        return new ArrayList<>(a);
    }

功能:将一个数组(变长参数的语法糖实现就是数组)转变成一个List(确切的来说是ArrayList),注意这个List是定长的,企图添加或者删除数据都会报错(java.lang.UnsupportedOperationException).
譬如案例1-1:

    List<Integer> list = Arrays.asList(3,4,2,1,5,7,6);
    System.out.println(list);

输出结果:[3, 4, 2, 1, 5, 7, 6]
但是,对于基础类型(比如byte,int,float等)千万不要想着这么实现(案例1-2,勿效仿):

    int a[] = new int[]{1,2,5,4,6,8,7,9};
    List list = Arrays.asList(a);

因为List list = Arrays.asList(a);会变成List

        for(int[] arr:list)
        {
            for(int i:arr)
            {
                System.out.println(i);
            }
        }

这样操作就显得非常的烦琐。因为预想List是List<Integer>形式的,没想到是List<int[]>形式的。使用的时候要特别的注意一下。


2. sort

对数组进行排序。适合byte,char,double,float,int,long,short等基本类型,还有Object类型(实现了Comparable接口),如果提供了比较器Comparator也可以适用于泛型。
案例2-1(基础类型,输出:[1, 1, 4, 4, 5, 6, 7, 9]):

        int a[] = new int[]{1,9,5,4,6,4,7,1};
        Arrays.sort(a);
        System.out.println(Arrays.toString(a));

案例2-2(String类型(Object),实现了Comparable接口,输出:[s1, s2, s3, s4]):

        String str[] = {"s2","s4","s1","s3"};
        Arrays.sort(str);
        System.out.println(Arrays.toString(str));

案例2-3 (自定义类型,实现了Comparable接口,输出:[jj:17, zzh:18, qq:19]):

        Person1 persons[] = new Person1[]{
                new Person1("zzh",18),new Person1("jj",17),new Person1("qq",19)
        };
        Arrays.sort(persons);
        System.out.println(Arrays.toString(persons));

案例2-4(泛型,如果类型没有实现Comparable接口,可以通过Comparator实现排序):

        Person2 persons2[] = new Person2[]{
                new Person2("zzh",18),new Person2("jj",17),new Person2("qq",19)
        };
        Arrays.sort(persons2,new Comparator<Person2>(){

            @Override
            public int compare(Person2 o1, Person2 o2)
            {
                if(o1 == null || o2 == null)
                    return 0;
                return o1.getAge()-o2.getAge();
            }

        });
        System.out.println(Arrays.toString(persons2));

输出:[jj:17, zzh:18, qq:19]
关于类Person1和类Person2的详细细节可以参考《Comparable与Comparator浅析


3. binarySearch

通过二分查找法对已排序(譬如经过Arrays.sort排序,且按照升序进行排序。如果数组没有经过排序,那么检索结果未知)的数组进行查找。适合byte,char,double,float,int,long,short等基本类型,还有Object类型和泛型(参考sort那段)
案例3-1:

        String str[] = {"s2","s4","s1","s3"};
        Arrays.sort(str);
        System.out.println(Arrays.toString(str));
        int ans = Arrays.binarySearch(str, "s1");
        System.out.println(ans);

输出:

[s1, s2, s3, s4]
0

4. copyOf

数组拷贝,底层采用System.arrayCopy(native方法)实现。
案例4-1:

        String str[] = {"s2","s4","s1","s3"};
        String str2[] = Arrays.copyOf(str, str.length);
        System.out.println(Arrays.toString(str2));

输出:[s2, s4, s1, s3]


5. copyOfRange

数组拷贝,指定一定的范围,譬如(public static T[] copyOfRange(T[] original, int from, int to))。底层采用System.arrayCopy(native方法)实现。
案例5-1:

        String str[] = {"s2","s4","s1","s3"};
        String str2[] = Arrays.copyOfRange(str,1,3);
        System.out.println(Arrays.toString(str2));

输出:[s4, s1]


6. equals和deepEquals

equals:判断两个数组的每一个对应的元素是否相等(equals, 对于两个数组的元素o1和o2有o1==null ? o2==null : o1.equals(o2))。
案例6-1:

        String str1[] = {"s2","s4","s1","s3",null};
        String str2[] = Arrays.copyOf(str1, str1.length);
        System.out.println(Arrays.equals(str1, str2));

输出:true
deepEquals:主要针对一个数组中的元素还是数组的情况,类似deepToString, deepHashCode如下:
案例6-1:

        int a1[] = new int[]{1,2,3};
        int a2[] = new int[]{1,3,3};
        int a3[] = new int[]{4,3,2,1};
        int a4[] = new int[]{1,2,3};
        int a5[] = new int[]{1,3,3};
        int a6[] = new int[]{4,3,2,1};
        int[] a [] = new int[][]{a1,a2,a3};
        int[] b [] = new int[][]{a4,a5,a6};

        System.out.println(Arrays.equals(a, b));
        System.out.println(Arrays.deepEquals(a, b));

输出结果:

false
true

7. fill

给数组赋值。填充数组之用。
案例7-1:

        String str[] = {"s2","s4","s1","s3",null};
        System.out.println(Arrays.toString(str));
        Arrays.fill(str, "s5");
        System.out.println(Arrays.toString(str));

输出:

[s2, s4, s1, s3, null]
[s5, s5, s5, s5, s5]

8. toString和deepToString

toString:对于一个数组int a[] = new int[]{1,9,5,4,6,4,7,1};如果按照System.out.println(a);打印企图可以打印出[1,9,5,4,6,4,7,1],实际上只会打印出[I@3e2de41d这种。在打印数组的时候需要写成Arrays.toString(a)的形式。可参考sort的详解。
deepToString:当数组中又包含数组,那么就不能单存的利用Arrays.toString()了,请看例子。
案例8-1:

        int a1[] = new int[]{1,2,3};
        int a2[] = new int[]{1,3,3};
        int a3[] = new int[]{4,3,2,1};
        int[] a [] = new int[][]{a1,a2,a3};
        System.out.println(Arrays.toString(a));
        System.out.println(Arrays.deepToString(a));

输出结果:

[[I@1b6b7f83, [I@2e807f85, [I@76340c9c]
[[1, 2, 3], [1, 3, 3], [4, 3, 2, 1]]

相信各位应该看到差别了吧。


9. hashCode和deepHashCode

hashCode:计算一个数组的hashCode.对于一个数组Object[], hashCode方法返回的值取决于:数组中每个元素的元素oi.hashCode()的值初级计算result = 31 * result + (oi== null ? 0 : oi.hashCode());
deepHashCode: 对于一个数组Object[], deepHashCode取决于:数组中每个元素oi,如果oi还是一个数组,那么就继续深入的去获取hashCode,这段比较绕,来个例子比较形象。
案例9-1:

        int a1[] = new int[]{1,2,3};
        int a2[] = new int[]{1,3,3};
        int a3[] = new int[]{4,3,2,1};
        int[] a [] = new int[][]{a1,a2,a3};
        System.out.println(Arrays.hashCode(a));
        System.out.println(Arrays.deepHashCode(a));

运行结果:

-1683374023
31646847

这样可以看到hashCode与deepHashCode的区别。对于数组而言hashCode只调用到它第一层元素,deepHashCode会一直调用直至不能再拆分成数组的元素。



参考资料:
1. 《Comparable与Comparator浅析

时间: 2024-10-22 02:29:07

Java集合框架:Arrays工具类的相关文章

fastutil 6.4.1发布 Java集合框架扩展工具

fastutil是一个Java集合框架的扩展工具,通过提供特定类型的地图,设置,列表和队列.目的是提供低http://www.aliyun.com/zixun/aggregation/17969.html">内存占用,快速访问和嵌入到Java应用.同时还提供了大数组(64位),进行设置和列出,二进制和文本文件的实用I/O类. fastutil 6.4.1版本修复了在TextIO.store()方法的错误,和大量设置的刷新. 软件信息:http://fastutil.dsi.unimi.it

JAVA集合框架之List接口实现类

上一篇博客<JAVA集合框架之Set接口实现类>中介绍了Set接口的相关实现类,这一篇将介绍List接口的实现类. java.util.ArrayList< E > ArrayList有点类似于数组,相比较于数组而言,ArrayList可以动态的更改元素个数,相对于数组较为灵活. 每个 ArrayList 实例都有一个容量.该容量是指用来存储列表元素的数组的大小.它总是至少等于列表的大小.随着向 ArrayList 中不断添加元素,其容量也自动增长.并未指定增长策略的细节,因为这不

JAVA集合框架之Set接口实现类

在上一篇<JAVA集合框架>中为大家介绍了JAVA集合框架的基本组成,这一片开始将为大家介绍集合框架中常用的实现类的用法. java.util.HashSet< E > 此类实现 Set 接口,由哈希表(实际上是一个 HashMap 实例)支持.它不保证 set 的迭代顺序:特别是它不保证该顺序恒久不变.此类允许使用 null 元素.这是我们最常用的Set接口的实现类. 构造方法 方法名 说明 HashSet() 构造一个新的空 set,其底层 HashMap 实例的默认初始容量是

Java程序员的日常—— Arrays工具类的使用

这个类在日常的开发中,还是非常常用的.今天就总结一下Arrays工具类的常用方法.最常用的就是asList,sort,toStream,equals,copyOf了.另外可以深入学习下Arrays的排序算法,这个还是非常有用的. 所有的方法都是在下面的类中进行测试的: public class ArraysTest { String[] array = new String[]{"a","c","2","1","b&

Java集合源码剖析:Java集合框架

Java集合工具包位于Java.util包下,包含了很多常用的数据结构,如数组.链表.栈.队列.集合.哈希表等.学习Java集合框架下大致可以分为如下五个部分:List列表.Set集合.Map映射.迭代器(Iterator.Enumeration).工具类(Arrays.Collections). Java集合类的整体框架如下: 从上图中可以看出,集合类主要分为两大类:Collection和Map. Collection是List.Set等集合高度抽象出来的接口,它包含了这些集合的基本操作,它主

[Java] 集合框架的层次结构和使用规则梳理

在Java语言中,Java语言的设计者对常用的数据结构和算法做了一些规范(接口)和实现(具体实现接口的类).所有抽象出来的数据结构和操作(算法)统称为Java集合框架(JavaCollectionFramework). Java程序员在具体应用时,不必考虑数据结构和算法实现细节,只需要用这些类创建出来一些对象,然后直接应用就可以了,这样就大大提高了编程效率. 概述 什么是框架?  类库的集合 什么是集合? 存放数据的容器 集合框架用来干什么? 用来表示和操作的统一的架构 集合框架包含了两部分:一

Java集合框架实现自定义排序

Java集合框架针对不同的数据结构提供了多种排序的方法,虽然很多时候我们可以自己实现排序,比如数组等,但是灵活的使用JDK提供的排序方法,可以提高开发效率,而且通常JDK的实现要比自己造的轮子性能更优化. 1.使用Arrays对数组进行排序 Java API对Arrays类的说明是:此类包含用来操作数组(比如排序和搜索)的各种方法. (1)使用Arrays排序 Arrays使用非常简单,直接调用sort()即可: 1 2 3 4 5 6 7 8 9 10 11 int[] arr = new i

Java集合框架:总结

最近博主对于Java集合框架这个系列做了一个整理,主要包括: Map系:HashMap, LinkedHashMap, TreeMap, WeakHashMap, EnumMap; List系:ArrayList, LinkedList, Vector, Stack; Set系:HashSet, LinkedHashSet, TreeSet; 工具类:Collections,Arrays 不过并没有对多线程(ConcurrentHashMap,BlockingQueue等)集合框架进行整理,以后

关于Java集合框架面试题(含答案)下_java

21.HashMap和HashTable有何不同? (1)HashMap允许key和value为null,而HashTable不允许. (2)HashTable是同步的,而HashMap不是.所以HashMap适合单线程环境,HashTable适合多线程环境. (3)在Java1.4中引入了LinkedHashMap,HashMap的一个子类,假如你想要遍历顺序,你很容易从HashMap转向LinkedHashMap,但是HashTable不是这样的,它的顺序是不可预知的. (4)HashMap