The previous section mainly introduced the basic concepts of arrays, and went a little deeper into what arrays are. In this blog post, we mainly introduce other aspects of arrays.
There are many ways to store a series of data in java, and are they much more convenient to operate than arrays? But why do we still need to use arrays instead of replacing them? Arrays differ from other kinds of containers in three areas: efficiency, type, and the ability to hold primitive types. In Java, an array is the most efficient way to store and randomly access a sequence of object references.
Arrays are used less and less in project design, and they are indeed not as convenient to use as List and Set. However, arrays still have some advantages in some aspects, such as speed, and the bottom layer of collection classes is also implemented through arrays.
--------这是ArrayList的add()------ public boolean add(E e) { ensureCapacity(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
The following uses arrays and lists to do some comparison operations.
## From the time above the time, consumption of the array of basic types of basic types is about 5 times the collection. In fact, in the list collection, there is a fatal action in the summation: list.get(i). This action is an unboxing action. The Integer object is automatically converted into an int basic type through the intValue method, which causes unnecessary performance consumption.
4. Variable length array?
The array is of fixed length, and once initialized and declared, the length cannot be changed. This is very inconvenient for us in actual development. If we are smart, we can definitely find a way to achieve it. Just as Java cannot implement multiple inheritance, we can also use internal classes and interfaces to achieve it (please refer to: Java Improvement Chapter (9) ----- Implementing Multiple Inheritance).
So how to implement a variable-length array? We can use the expansion idea in the List collection add method to simulate the implementation. Below is ArrayList's expansion method: # 下 下
#This code is useful for us in the if statement later. The idea is to copy the original array to a new array, and the new array is 1.5 times the length of the original array. So the simulated array expansion code is as follows:
Long time1 = System.currentTimeMillis();
for(int i = 0 ; i < 100000000 ;i++){
sum += arrays[i%10];
}
Long time2 = System.currentTimeMillis();
System.out.println("数组求和所花费时间:" + (time2 - time1) + "毫秒");
Long time3 = System.currentTimeMillis();
for (int i = 0; i < 100000000; i++) {
sum += list.get(i%10);
}
Long time4 = System.currentTimeMillis();
System.out.println("List求和所花费时间:" + (time4 - time3) + "毫秒");
--------------Output:
数组求和所花费时间:696毫秒
List求和所花费时间:3498毫秒
Expansion. Therefore, if you really need a variable-length data set in your project, arrays are also within the scope of consideration. We cannot exclude them because they are of fixed length! Copying one by one is very troublesome, so I simply use the List.toArray() method to convert it into an array and then copy it through Arrays.copyOf. After converting it into a collection, I personally find it very convenient, but I don’t know that I have fallen into the trap. ! We know that if the array elements are objects, the data in the array are object references
public void ensureCapacity(int minCapacity) { modCount++; int oldCapacity = elementData.length; /** * 若当前需要的长度超过数组长度时进行扩容处理 */ if (minCapacity > oldCapacity) { Object oldData[] = elementData; int newCapacity = (oldCapacity * 3) / 2 + 1; //扩容 if (newCapacity < minCapacity) newCapacity = minCapacity; //拷贝数组,生成新的数组 elementData = Arrays.copyOf(elementData, newCapacity); } }
有关于深浅拷贝的博文,参考:
我们经常需要使用到Arrays这个工具的asList()方法将其转换成列表。方便是方便,但是有时候会出现莫名其妙的问题。如下:
public static void main(String[] args) { int[] datas = new int[]{1,2,3,4,5}; List list = Arrays.asList(datas); System.out.println(list.size()); } ------------Output: 1
结果是1,是的你没有看错, 结果就是1。但是为什么会是1而不是5呢?先看asList()的源码
public static <T> List<T> asList(T... a) { return new ArrayList<T>(a); }
注意这个参数:T…a,这个参数是一个泛型的变长参数,我们知道基本数据类型是不可能泛型化的,也是就说8个基本数据类型是不可作为泛型参数的,但是为什么编译器没有报错呢?这是因为在java中,数组会当做一个对象来处理,它是可以泛型的,所以我们的程序是把一个int型的数组作为了T的类型,所以在转换之后List中就只会存在一个类型为int数组的元素了。所以我们这样的程序System.out.println(datas.equals(list.get(0)));输出结果肯定是true。当然如果将int改为Integer,则长度就会变成5了。
我们在看下面程序:
enum Week{Sum,Mon,Tue,Web,Thu,Fri,Sat} public static void main(String[] args) { Week[] weeks = {Week.Sum,Week.Mon,Week.Tue,Week.Web,Week.Thu,Week.Fri}; List<Week> list = Arrays.asList(weeks); list.add(Week.Sat); }
这个程序非常简单,就是讲一个数组转换成list,然后改变集合中值,但是运行呢?
Exception in thread "main" java.lang.UnsupportedOperationException at java.util.AbstractList.add(AbstractList.java:131) at java.util.AbstractList.add(AbstractList.java:91) at com.array.Test.main(Test.java:18)
编译没错,但是运行竟然出现了异常错误!UnsupportedOperationException ,当不支持请求的操作时,就会抛出该异常。从某种程度上来说就是不支持add方法,我们知道这是不可能的!什么原因引起这个异常呢?先看asList()的源代码:
public static <T> List<T> asList(T... a) { return new ArrayList<T>(a); }
这里是直接返回一个ArrayList对象返回,但是注意这个ArrayList并不是java.util.ArrayList,而是Arrays工具类的一个内之类:
private static class ArrayList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable{ private static final long serialVersionUID = -2764017481108945198L; private final E[] a; ArrayList(E[] array) { if (array==null) throw new NullPointerException(); a = array; } /** 省略方法 **/ }
但是这个内部类并没有提供add()方法,那么查看父类:
public boolean add(E e) { add(size(), e); return true; } public void add(int index, E element) { throw new UnsupportedOperationException(); }
这里父类仅仅只是提供了方法,方法的具体实现却没有,所以具体的实现需要子类自己来提供,但是非常遗憾
这个内部类ArrayList并没有提高add的实现方法。在ArrayList中,它主要提供了如下几个方法:
1、size:元素数量
2、toArray:转换为数组,实现了数组的浅拷贝。
3、get:获得指定元素。
4、contains:是否包含某元素。
So to sum up, asList returns a list with immutable length. How long is the array and how long is the converted list? We cannot increase or decrease its length through add or remove.
The above is the content of Java Improvement Chapter (19)-----Array 2. For more related content, please pay attention to the PHP Chinese website (www.php.cn)!