天天看点

插曲--关于数组和集合的转换

插个东西,今天先不写mr,下午再写,刚刚搞了一个问题,觉得自己真是学了不少,长见识了,之前只知道数组和集合之间可以互相转换,今天写mr的时候,有一个功能是要求列出三个数组中的共同元素,于是我很 xx 的写下了三层for循环:

String[] s1 = {"a","b","c","d"};

String[] s2 = {"b","c","d","e"};

String[] s3 = {"c","d","e","f"};

if(s1 != null && s2 != null && s3 != null){

List<String> arrayList = new ArrayList<String>();

for (int i = 0; i < s1.length; i++) {

for (int j = 0; j < s2.length; j++) {

for (int k = 0; k < s3.length; k++) {

if(s1[i].equals(s2[j]) && s2[j].equals(s3[k])){

arrayList.add(s3[k]);

}

}

}

}

System.out.println(arrayList.toString());

}

这样写完肯定是不行的,之后开始优化一下:

if(s1 != null && s2 != null && s3 != null){

List<String> arraylist = new ArrayList<>();

for (int i = 0; i < s1.length; i++) {

for (int j = 0; j < s2.length; j++) {

if(s1[i].equals(s2[j])){

for (int k = 0; k < s3.length; k++) {

if(s2[j].equals(s3[k])){

arraylist.add(s3[k]);

}

}

}

}

}

System.out.println(arrayList.toString());

}

这样写完的确是减少一些循环的次数,但是为了让代码看着简洁,于是我就想着要不先转换成集合,然后集合里面的方法多,可以找找看有没有合适的,于是找到了,retainAll可以留下共同的元素,就算不能想StringBuilder级联使用,就算底层也是for循环,但外面看着是好看些,于是我开始把数组转换成集合,于是乎。。。

List<String> list1 = Arrays.asList(s1);

List<String> list2 = Arrays.asList(s2);

List<String> list3 = Arrays.asList(s3);

list1.retainAll(list2);

list1.retainAll(list3);

于是我就开始碰见这个问题了,“Exception in thread "main" java.lang.UnsupportedOperationException” 提示我没这操作,我好像也没写错什么啊,就这么简单的两句话,我好像真的没有写错什么啊,然后我就开始看retainAll这个方法,我调用的也对啊。。。

最后问了大神欧巴又度娘了,才知道不是方法的问题而是asList返回的是固定长度的数组,源码里也写了是个fixed-array,既然是固定肯定是不能添加删除的,只能用一些数组之前的操作,然后我就写了下面的方法,也提醒自己集合里面的方法好多不用自己都忘记了,还是要经常温故而知新的。

List<String> list1 = Arrays.asList(s1);

list1 = new ArrayList<>(list1);

List<String> list2 = Arrays.asList(s2);

list2 = new ArrayList<>(list2);

List<String> list3 = Arrays.asList(s3);

list3 = new ArrayList<>(list3);

list1.retainAll(list2);

list1.retainAll(list3);

这样就可以得到三个数组共有的元素了,这样写表面上是简洁了很多,但是底层仍然是for循环,所以都一样的,并且retainAll这个方法还要注意,会删除掉所有不同的元素,原集合会发生改变,这也是有一定代价的。

PS:我看别的博客也有使用ArrayUtils.toObject(T[] t)这个方法的,但是对于字符串行不通,而且还要Apache-common下面的包,反正我在hadoop上是能找到这个方法。

另外:

也写一下集合转换成数组的方法:

T[] t = new T[集合实现类.size()];

集合实现类.toArray(T[] t);