(Java基础) List转换为数组 & 数组转换为List
前言
前段时间, 一直看到Spark
内的一处进行序列化的语句. 想起来之前看过Arrays
的源代码. 于是, 在此总结一下.
String [] array = new String[]{"a","b","c"};
JavaRDD<String> javaRDDTmp = new JavaSparkContext(new SparkConf().setMaster("SEAN-YANXML")).parallellize(Array.asList(array));
其实. 值得注意的是Spark
内的RDD
都是不可变的. 所以, 这里的转换没有问题. 但是在我们日常的开发中, 转换可变的数组的时候, 是不可以这样进行转换的.
转换操作
数组Array -> List
错误做法
// Array -> List 错误示范.
public static void testFromArrayToListError() {
String [] array = new String[] {"A","BC","DEFE"};
// 方法2 不太好 会报出异常
List<String> stringList = Arrays.asList(array);
// stringList.add("B");
}
不可变List. 如果添加元素会报如下异常.
// Exception in thread "main" java.lang.UnsupportedOperationException
//at java.util.AbstractList.add(AbstractList.java:148)
//at java.util.AbstractList.add(AbstractList.java:108)
//at com.yanxml.util.convert.ArrayToList.testFromArrayToList(ArrayToList.java:13)
//at com.yanxml.util.convert.ArrayToList.main(ArrayToList.java:24)
原因: 转变的ArrayList是Arrays的局部类. 而非我们平时使用的ArrayList
.
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) {
a = Objects.requireNonNull(array);
}
@Override
public int size() {
return a.length;
}
@Override
public Object[] toArray() {
return a.clone();
}
@Override
@SuppressWarnings("unchecked")
public <T> T[] toArray(T[] a) {
int size = size();
if (a.length < size)
return Arrays.copyOf(this.a, size,
(Class<? extends T[]>) a.getClass());
System.arraycopy(this.a, 0, a, 0, size);
if (a.length > size)
a[size] = null;
return a;
}
@Override
public E get(int index) {
return a[index];
}
@Override
public E set(int index, E element) {
E oldValue = a[index];
a[index] = element;
return oldValue;
}
@Override
public int indexOf(Object o) {
E[] a = this.a;
if (o == null) {
for (int i = 0; i < a.length; i++)
if (a[i] == null)
return i;
} else {
for (int i = 0; i < a.length; i++)
if (o.equals(a[i]))
return i;
}
return -1;
}
@Override
public boolean contains(Object o) {
return indexOf(o) != -1;
}
@Override
public Spliterator<E> spliterator() {
return Spliterators.spliterator(a, Spliterator.ORDERED);
}
@Override
public void forEach(Consumer<? super E> action) {
Objects.requireNonNull(action);
for (E e : a) {
action.accept(e);
}
}
@Override
public void replaceAll(UnaryOperator<E> operator) {
Objects.requireNonNull(operator);
E[] a = this.a;
for (int i = 0; i < a.length; i++) {
a[i] = operator.apply(a[i]);
}
}
@Override
public void sort(Comparator<? super E> c) {
Arrays.sort(a, c);
}
}
可以看到. 其内并没有实现AbstartList
内的add()
方法.
正确做法
// Array -> List 正确示范
public static void testFromArrayToList() {
String []array = new String[] {"A","BC","DEFE"};
// 正确方法1
List<String> stringListA = new ArrayList<>(Arrays.asList(array));
stringListA.add("OPP");
// 正确方法2
List<String> stringListB = new ArrayList<>(array.length);
Collections.addAll(stringListB,array);
// 正确方法3
List<String> stringListC = new ArrayList<>(array.length);
for(String str:array) {
stringListC.add(str);
}
}
List -> Array
错误做法
// List -> String [] 错误示范
public static void testFromListToArrayError() {
List<String> stringList = new ArrayList<String>();
stringList.add("a");
stringList.add("b");
String[] stringArray = (String[])stringList.toArray();
}
如上写法. 会报强制转换异常. 因为 toArray()
转换的是Object[]
. 父类无法强制转换为子类对象的.
// Exception in thread "main" java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Ljava.lang.String;
// at com.yanxml.util.convert.ArrayToList.testFromListToArray(ArrayToList.java:34)
// at com.yanxml.util.convert.ArrayToList.main(ArrayToList.java:39)
正确写法
// List -> String[] 正确示范
public static void testFromListToArray() {
// 方法1
List<String> stringList = new ArrayList<String>();
stringList.add("a");
stringList.add("b");
String[] stringArrayA = stringList.toArray(new String[stringList.size()]);
// 方法2
String[] stringArrayB = new String[stringList.size()];
for(int i=0;i<stringList.size();i++) {
stringArrayB[i] = stringList.get(i);
}
}
Reference
[1]. java List和数组相互转换方法
还没有评论,来说两句吧...