Arrayutils常用方法
-
toString 将一个数组转换成String,用于打印数组
isEquals 判断两个数组是否相等,采用EqualsBuilder进行判断
toMap 将一个数组转换成Map,如果数组里是Entry则其Key与Value就是新Map的Key和Value,如果是Object[]则Object[0]为Key,Object[1]为Value
clone 拷贝数组
subarray 截取子数组
isSameLength 判断两个数组长度是否相等
getLength 获得数组的长度
isSameType 判段两个数组的类型是否相同
reverse 数组反转
indexOf 查询某个Object在数组中的位置,可以指定起始搜索位置
lastIndexOf 反向查询某个Object在数组中的位置,可以指定起始搜索位置
contains 查询某个Object是否在数组中
toObject 将基本数据类型转换成外包型数据
isEmpty 判断数组是否为空(null和length=0的时候都为空)
addAll 合并两个数组
add 添加一个数据到数组
remove 删除数组中某个位置上的数据
removeElement 删除数组中某个对象(从正序开始搜索,删除第一个)
引用包
import java.lang.reflect.Array;//此类提供了动态创建和访问 Java 数组的方法 import java.util.Arrays; //此类包含用来操作数组(比如排序和搜索)的各种方法 import java.util.HashMap; import java.util.HashSet; import java.util.Map; import org.apache.commons.lang3.builder.EqualsBuilder; import org.apache.commons.lang3.builder.HashCodeBuilder; import org.apache.commons.lang3.builder.ToStringBuilder; import org.apache.commons.lang3.builder.ToStringStyle; import org.apache.commons.lang3.mutable.MutableInt;
通过引用包可以看到ArrayUtils对Array的操作,并对Arrays进行一定的封装,并使用多个自定义的Builder进行辅助
1.null对象
public static final Object[] EMPTY_OBJECT_ARRAY = new Object[0]; public static final Class<?>[] EMPTY_CLASS_ARRAY = new Class[0]; public static final int INDEX_NOT_FOUND = -1;
一开始有很多类似这样的对象,和一个null索引,用null对象代替null
2.toString 打印数组
public static String toString(Object array) { return toString(array, "{}"); } public static String toString(Object array, String stringIfNull) { if(array == null) return stringIfNull; else return (new ToStringBuilder(array, ToStringStyle.SIMPLE_STYLE)).append(array).toString(); }
这个简单,用了个ToStringBuilder
3.isEquals 判断数组内容是否相等
public static boolean isEquals(Object array1, Object array2) { return new EqualsBuilder().append(array1, array2).isEquals(); }
public EqualsBuilder append(Object lhs, Object rhs) { if (isEquals == false) { return this; } if (lhs == rhs) { return this; } if (lhs == null || rhs == null) { this.setEquals(false);//并不是isEquals = false; return this; } Class<?> lhsClass = lhs.getClass(); if (!lhsClass.isArray()) { // The simple case, not an array, just test the element isEquals = lhs.equals(rhs);//判断依据 } else if (lhs.getClass() != rhs.getClass()) { // Here when we compare different dimensions, for example: a boolean[][] to a boolean[] this.setEquals(false); } // 'Switch' on type of array, to dispatch to the correct handler // This handles multi dimensional arrays of the same depth else if (lhs instanceof long[]) { append((long[]) lhs, (long[]) rhs); } else if (lhs instanceof int[]) { append((int[]) lhs, (int[]) rhs); } else if (lhs instanceof short[]) { append((short[]) lhs, (short[]) rhs); } else if (lhs instanceof char[]) { append((char[]) lhs, (char[]) rhs); } else if (lhs instanceof byte[]) { append((byte[]) lhs, (byte[]) rhs); } else if (lhs instanceof double[]) { append((double[]) lhs, (double[]) rhs); } else if (lhs instanceof float[]) { append((float[]) lhs, (float[]) rhs); } else if (lhs instanceof boolean[]) { append((boolean[]) lhs, (boolean[]) rhs); } else { // Not an array of primitives append((Object[]) lhs, (Object[]) rhs); } return this; }
注意到几点
1通过set赋值,其他的不说,至少在有==的情况下不容易迷惑- -
2if一行也加{},至少我很少这样做
3面向对象,如果我来写,isEquals 应该更像一个过程
4.toMap
public static Map<Object, Object> toMap(Object[] array) { if (array == null) { return null; } final Map<Object, Object> map = new HashMap<Object, Object>((int) (array.length * 1.5));//看见int,第一反应是撑爆他,不过我输了 for (int i = 0; i < array.length; i++) { Object object = array[i]; if (object instanceof Map.Entry<?, ?>) { Map.Entry<?,?> entry = (Map.Entry<?,?>) object; map.put(entry.getKey(), entry.getValue());//没有直接使用object } else if (object instanceof Object[]) { Object[] entry = (Object[]) object; if (entry.length < 2) { throw new IllegalArgumentException("Array element " + i + ", '" + object + "', has a length less than 2"); } map.put(entry[0], entry[1]); } else { throw new IllegalArgumentException("Array element " + i + ", '" + object + "', is neither of type Map.Entry nor an Array"); } } return map; }
1final,Map.Entry 以后再说
2最终处理的对象都是entry
5.toArray
public static <T> T[] toArray(final T... items) {//可变长度 return items; }
新的创建数组的方式
6.subarray截取
public static int[] subarray(int[] array, int startIndexInclusive, int endIndexExclusive) { if (array == null) { return null; } if (startIndexInclusive < 0) { startIndexInclusive = 0; } if (endIndexExclusive > array.length) { endIndexExclusive = array.length; } int newSize = endIndexExclusive - startIndexInclusive; if (newSize <= 0) { return EMPTY_INT_ARRAY; } int[] subarray = new int[newSize]; System.arraycopy(array, startIndexInclusive, subarray, 0, newSize); return subarray; }
截取什么的最讨厌了,索引还是长度弄不清楚的话每次都要实验,可以明显的发现startIndexInclusive和endIndexExclusive结尾单词不一样,不过我没法很好的翻译他们,直接看代码可以很清楚知道Inclusive就是索引,Exclusive是长度,即索引额外的+1
7.reverse 反转
public static void reverse(Object[] array) { if (array == null) { return; } int i = 0; int j = array.length - 1; Object tmp; //写在循环外 while (j > i) { tmp = array[j]; array[j] = array[i]; array[i] = tmp; j--; i++; } }
8.indexOf 查找
public static int indexOf(Object[] array, Object objectToFind, int startIndex) { if (array == null) { return INDEX_NOT_FOUND; } if (startIndex < 0) { startIndex = 0; } if (objectToFind == null) { for (int i = startIndex; i < array.length; i++) { if (array[i] == null) { return i; } } } else if (array.getClass().getComponentType().isInstance(objectToFind)) { for (int i = startIndex; i < array.length; i++) { if (objectToFind.equals(array[i])) {//根据equals判断 return i; } } } return INDEX_NOT_FOUND; }
9.contains
public static boolean contains(Object[] array, Object objectToFind) { return indexOf(array, objectToFind) != INDEX_NOT_FOUND; }
其他的都很简单,不在贴了,总结下心得
Object 终究代替不了一切,特殊的类型的方法还是得c+v,null对象代替null,通过set赋值,if一行也加{},同一个方法最终处理的对象具有相同的名字,final和内部类得用用,命名还是需要专业英语(受够了拼音缩写)以及面向对象(build辅助类)