本文整理Java数组和集合操作的惯用法。

数组填充与复制

填充数组元素

byte[] a = new byte[3];
Arrays.fill(a, (byte)123);

复制一个范围内的数组元素

// Copy 8 elements from array 'a' starting at offset 3
// to array 'b' starting at offset 6,
// assuming 'a' and 'b' are distinct arrays
byte[] a = (...);
byte[] b = (...);

System.arraycopy(a, 3, b, 6, 8);

调整数组大小

a = Arrays.copyOf(a, newLen);

可变参数列表转范型数组

public class Test {
   public static void main(String[] args) {
       Integer[] a = of(1, 2, 3);
       String[] b = of("hello", "world");
   }

   private static <T> T[] of(T... values) {
       return values;
   }
}

数组与ArrayList互转

数组转ArrayList

方法1:使用Arrays.asList,返回Arrays的内部静态类ArrayList,是传入的数组参数的一个视图,性能较好,不支持写操作add等,不过可以通过索引修改元素内容

String[] str = { "a", "b" };
// 或 String[] str = new String[] { "a", "b" };
List<String> list = Arrays.asList(str);

// 因为是视图,修改内容会导致数组元素内容也被修改
list[0]= "suninf";

// add 抛异常: java.lang.UnsupportedOperationException
// list.add("c"); 

方法2:转为java.util.ArrayList

String[] str = new String[] { "a", "b" };
List<String> arrayList = new ArrayList<>(Arrays.asList(arrays));
arrayList.add("c");

方法3:使用Java8 Stream

String[] strArray = new String[] { "a", "b" };
List<String> listStrings = Stream.of(strArray).collect(Collectors.toList());

方法4:使用Guava的Lists.newArrayList

String[] strArray = new String[] { "a", "b" };
List<String> ss = Lists.newArrayList(strArray);

newArrayList内部实现是:

public static <E> ArrayList<E> newArrayList(E... elements) {
    Preconditions.checkNotNull(elements);
    int capacity = computeArrayListCapacity(elements.length);
    ArrayList<E> list = new ArrayList(capacity);
    Collections.addAll(list, elements);
    return list;
}

ArrayList转数组

方法1:使用List.toArray方法

    List<String> list = new ArrayList<String>();
    list.add("A");
    list.add("B");

    // 使用泛型,无需显式类型转换
    String[] array = list.toArray(new String[list.size()]);
    System.out.println(array[0]);

方法2:使用Stream

String[] ss = list.stream().toArray(String[]::new);

集合操作使用stream和函数式编程

Java8加了stream和lambda机制,表达能力得到大大提升

public static List<String> getModelsAfter2000UsingPipeline(
    List<Car> cars) {
    return 
      cars.stream()
          .filter(car > car.getYear() > 2000)
          .sorted(Comparator.comparing(Car::getYear))
          .map(Car::getModel)
          .collect(toList());
  }