Use arrays.asList to convert data to the three pits of List

You can’t directly use arrays.aslist to convert primitives

int[] arr = {1, 2, 3}; List list = Arrays.asList(arr); log.info("list:{} size:{} class:{}", list, list.size(), list.get(0).getClass()); / / the size: 1Copy the code

So this List is actually an array of ints, and the whole List is one, and the element type is an array of integers.

The reason is that you can only box an int as an Integer, not an int array as an Integer array. As we know, Arrays. AsList passes in a generic T variable and ends up with an int array as an object that becomes a generic T:

public static <T> List<T> asList(T... a) {
    return new ArrayList<>(a);
}
Copy the code

Arrays.stream can be used with Java8 +; otherwise, int Arrays can be declared as wrapped Integer Arrays:

int[] arr1 = {1, 2, 3};
List list1 = Arrays.stream(arr1).boxed().collect(Collectors.toList());
log.info("list:{} size:{} class:{}", list1, list1.size(), list1.get(0).getClass());


Integer[] arr2 = {1, 2, 3};
List list2 = Arrays.asList(arr2);
log.info("list:{} size:{} class:{}", list2, list2.size(), list2.get(0).getClass());
Copy the code

The List returned by arrays.aslist does not support addition or deletion, and changes to the original array will affect the List we got

String[] arr = {"1", "2", "3"};
List list = Arrays.asList(arr);
arr[1] = "4";
try {
    list.add("5");
} catch (Exception ex) {
    ex.printStackTrace();
}
log.info("arr:{} list:{}", Arrays.toString(arr), list);
Copy the code

Log in an UnsupportedOperationException, for the operation of the new string List 5 failed, and the second element of an array of the original from 2 to 4, asList won the second element of the List has been modified to 4:

java.lang.UnsupportedOperationException at java.util.AbstractList.add(AbstractList.java:148) at java.util.AbstractList.add(AbstractList.java:108) at org.geekbang.time.commonmistakes.collection.aslist.AsListApplication.wrong2(AsListApplication.java:41) at Org.geekbang.time.com monmistakes. Collection. Aslist. AsListApplication. Main (AsListApplication. Java: 15) 13:15:34. 699 (main)  INFO org.geekbang.time.commonmistakes.collection.aslist.AsListApplication - arr:[1, 4, 3] list:[1, 4, 3]Copy the code

AsList doesn’t return the java.util.ArrayList we’d expect, but ArrayList, the inner class of Arrays. Inside the ArrayList class inherits from AbstractList class, there is no overriding the add method of the parent, and the implementation of the add method in the parent class, is to throw an UnsupportedOperationException.

ArrayList initializes the List returned from Array. asList

String[] arr = {"1", "2", "3"};
List list = new ArrayList(Arrays.asList(arr));
arr[1] = "4";
try {
    list.add("5");
} catch (Exception ex) {
    ex.printStackTrace();
}
log.info("arr:{} list:{}", Arrays.toString(arr), list);
Copy the code

The List. SubList slicing operation results in OOM

SubList is equivalent to a view of the original List, so there are two ways to fix it to avoid interaction:

  • One way is not to use the subList returned by subList directly, but to reuse the new ArrayList, passing subList in the constructor to build a separate ArrayList.

  • Alternatively, using the Skip and Limit apis of Stream for Java 8 to skip elements in the Stream and limit the number of elements in the Stream can also achieve SubList slicing.

    List subList = new ArrayList<>(list.sublist (1, 4));

    // List subList = list.stream().skip(1).limit(3).collect(Collectors. ToList ());

Make sure the right data structure does the right thing

Use data structures without considering balancing time and space

To perform a single Value search on a large List, consider using a HashMap, where the Key is the Value to be searched and the Value is the original object, which provides a significant performance advantage over using an ArrayList.

Even if we want to search not for single values but for conditional intervals, we can try using HashMap for “search performance optimization.” If your conditional intervals are fixed, you can group hashMaps by conditional intervals in advance, with keys being different intervals.

Indeed, if you have frequent large ArrayList searches in your business code, performance is much better using HashMap. Similarly, if you want to deduplicate a large ArrayList, you are not advised to use the contains method. Instead, you can consider using HashSet for deduplicating.

ObjectSizeCalculator is used to print the memory usage of ArrayList and HashMap. ArrayList occupies 21M of memory, while HashMap occupies 72M, more than three times as much memory as List.

In the case of tight application memory, we need to consider whether it is worthwhile to use more memory consumption in exchange for higher performance. What we see here is the art of balance, space for time, or time for space, and it is wrong to consider only one aspect.

Too much faith in textbook time complexity

LinkedList is suitable for adding and deleting elements. LinkedList is selected as the data structure. In real scenarios, read, write, add, and delete are generally balanced. In addition, adding and deleting cannot only be performed on the end and end objects, and performance gains may not be achieved in 90% of cases. Therefore, you are advised to evaluate the performance before using the data.

100 Common Mistakes in Java Business Development