[疯狂Java]数组:Arrays(数组工具类)

来源:互联网 发布:小狐仙网络电影 编辑:程序博客网 时间:2024/05/18 04:01

1. Arrays工具类简介:

    1) 是Java提供的专门用来操作数组的工具类,里面有一大堆静态方法(算法)来操作数组,低位就相当于C++ STL的<algorithm>库,只不过Arrays里面全部都是操作数组的算法,于此类似的是Collections工具类,里面全部都是操作集合的算法;

    2) 里面大致分为两类方法,一类是单线方法(用于单线程处理数组),另一类是多线算法(大多以parallel作为前缀,可以充分利用现代CPU多核并行的特点多线程处理数组,特别是对于那些规模非常庞大的数组);


!!接下来介绍的全部都是Arrays工具类的static静态工具方法;

!!所有的from - to的区间都是左闭右开的!!即[from, to);


!!单线方法:


2. 查找:

    1) int binarySearch(type[] a, typekey);  // 在数组a中二分查找元素key,返回第一个找到的key的索引

    2) int binarySearch(type[] a, int fromIndex, int toIndex, typekey); // 锁定索引范围[from, to)内二分查找

!!二分查找的前提是数组已经升序排列好了,如果key没找到则返回-1;


3. 排序:

    1) void sort(type[] a);  // 对a升序排列

    2) void sort(type[] a, int fromIndex, int toIndex);  // 对区间[from, to)升序排列

!!Arrays的sort并没有提供指定降序排列的参数,如果非要降序那就倒序迭代构造一个新的数组了!


4. 相等比较:boolean equals(type[] a, type[] a2);  // 只有两个数组长度相等,并且每个元素也对应相等时才会返回true


!!对于排序、查找、相等比较,如果数组元素的类型是自定义类型则必须要实现compareTo方法可以让这些算法对数组元素进行比较才行!和C++的<、==重载的道理是一样的;


4. 拷贝:

    1) type[] copyOf(type[] original, int length); // 赋值original数组的前length个元素形成一个新数组返回,如果length大于original的长度,那么多出来的部分系统自动赋予默认值(0/null);

    2) type[] copyOfRange(type[] original, int from, int to);  // 拷贝[from, to)区间,如果to超出original的长度,那么超出部分赋予0/null;

!!除此之外,如果填拷贝的量特别巨大,则应该考虑使用操作系统的memcpy系统调用了,毕竟系统调用的内存填充(复制)的效率是最最高的,Java的将该系统调用包装在System里(System本身就表示OS平台,OS的很多系统调用都在该类中有包装器),其静态方法arraycopy就是memscpy的包装:

static native void System.arraycopy(Object src,  int  srcPos,                                        Object dest, int destPos,                                        int length);
!意思非常明确,就是将src从srcPos开始的length长度拷贝到dest从destPos开始的位置处,其参数跟memcpy是一致的;


5. 填充:

    1) void fill(type[] a, type val);  // 整个数组填充val

    2) void fill(type[] a, int fromIndex, int toIndex, type val); // 区间填充


6. 连缀成字符串:String toString(type[] a);  // 分别调用各个元素的toString,将各个结果连缀成一个完整的String返回,中间用", "(逗号+空格分隔);

!!如果数组元素是自定义类型就必须自己实现toString方法才行;


!!多线方法:都以parallel作为前缀,表示并行计算


7. 排序:

    1) void parallelSort(type[] a);

    2) void parallelSort(type[] a, int fromIndex, int toIndex);


8. 二元迭代:

    1) void parallelPrefix(type[] a, int from, int to, typeBinaryOperator op);

        i. 表示将数组a的[from, to)进行typeBinaryOperator的二元迭代;

        ii. 其中BinaryOperator就是二元操作符的意思;

        iii. 该方法的意思其实就是以下代码:

static void parallelPrefix(type[] a, int from, int to, TypeBinaryOperator op) {for (int i = from; i < to; i++) {type left = (i == 0)? 1: a[i - 1]; // 对于第一个元素left = 1type right = a[i];a[i] = left op right;}}
!即从头到尾逐个按照left op right的方式更新,那更新后的值继续迭代下一个元素

        iv. 其中typeBinaryOperator表示二元运算法,type目前基本支持Java的基础类型(int、double等),该运算法其实是一个函数式接口,里面只有一个方法:

public interface TypeBinaryOperator {    type applyAsInt(type left, type right);}
!!例如上面的如果想使用连乘迭代那就可以直接用Lambda表达式:Arrays.parallelPrefix(arr, 1, 5, (left, right) -> left * right);就行了;

    2) 不指定区间的版本:void parallelPrefix(type[] a, typeBinaryOperator op); // 默认区间就是全部[0, length] == [0, length + 1);

!!如果是数组[1, 2, 3, 4, 5]进行全区间的连乘迭代,得到的结果就是[1, 2, 6, 24, 120];


9. 填充:

    1) void parallelSetAll(type[] a, TypeUnaryOperator op);

    2) 该方法就是用填充算法为数组a的每个元素赋值;

    3) UnaryOperator是一元运算符的意思,之所以是一元是因为该方法默认用元素的索引来生成该元素的值,该接口也是一个函数式接口:

public interface TypeUnaryOperator {    type applyAsInt(type operand); // 利用索引生成一个值,如何生成自己定义}
    4) 该方法的意思就是:

static void parallelSetAll(Type[] a, TypeUnaryOperator op) {for (int i = 0; i < a.length; i++) {a[i] = op(i);}}
    5) 例如:Arrays.parallelSetAll(a, index -> index * 5); // 一个长度为5的int数组其填充结果就是[0, 5, 10, 15, 20]




1 0
原创粉丝点击