偶然看到一篇文章,讲述在开发过程中程序员经常犯的一些错误,对比了了一下自己写的代码,发现有些东西确实没考虑到,以后将这些问题以及代码审查发现的问题做一个记录,提醒自己。
更多问题可参考 https://blog.csdn.net/qq_36894974/article/details/120666830
一,Array 转 ArrayList
public static void main(String[] args) {
Integer[] arr = new Integer[]{1, 2, 3, 4, 5, 6};
// ArrayList<Integer> arrayList = Arrays.asList(arr);
/* ↑这样转是会报错的,Arrays.asList() 将返回一个 ArrayList,它是 Arrays 中的私有静态类,它不是 java.util.ArrayList类。
Arrays 内部的 ArrayList 只有 set、get、contains 等方法,但是没有能够像是 add 这种能够使其内部结构进行改变的方法,
所以 Arrays 内部的 ArrayList 的大小是固定的。
如果要创建一个能够添加元素的 ArrayList ,你可以使用下面这种创建方式:
*/
ArrayList<Integer> arrayList2 = new ArrayList<>(Arrays.asList(arr));//ArrayList 的构造方法是可以接收一个 Collection 集合的,所以这种创建方式是可行的。
}
二,检查数组中是否包含某个值
public static void main(String[] args) {
//利用集合中的contains方法来快速得到结果
Integer[] arr = new Integer[]{1, 2, 3, 4, 5, 6};
//1,for循环遍历
//2,将数组转为集合,再用contains方法判断
ArrayList<Integer> arrayList = new ArrayList<>(Arrays.asList(arr));
System.out.println(arrayList.contains(5));
}
三,List中“循环”删除元素
public static void main(String[] args) {
//有时候可能要去掉List中指定范围的值,这时候不能用for 或 foreach 循环删除
ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (int i = 0; i < list.size(); i++) {
list.remove(i);
}
System.out.println(list);//b,d,使用for循环删除list里面的元素时会实时的改变元素,它并不像数组可以用下标操作,实时操作会实时改变集合的大小
ArrayList<String> list2 = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
for (String s : list2) {
if (s.equals("a"))
list2.remove(s);//java.util.ConcurrentModificationException 异常
//Vector、ArrayList在迭代的时候如果同时对其进行修改就会抛出java.util.ConcurrentModificationException异常
}
ArrayList<String> list3 = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
Iterator<String> iter = list3.iterator();
while (iter.hasNext()) {
String s = iter.next();//.next() 必须在 .remove() 之前调用。 在 foreach 循环中,编译器会在删除元素的操作后调用 .next(),导致ConcurrentModificationException。
if (s.equals("a")) {
iter.remove();
}
}
System.out.println(list3);
}
四,泛型擦除
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("1");
List<Integer> list2 = new ArrayList<>();
list2.add(1);
System.out.println(list1.getClass() == list2.getClass());//类型擦除,两个不同泛型的List相比较还是为true
List<String> list = new ArrayList<>();
add(list, 10);//JVM的类型擦除
/*
Java 的泛型是伪泛型,这是因为 Java 在编译期间,所有的泛型信息都会被擦掉,正确理解泛型概念的首要前提是理解类型擦除。
Java 的泛型基本上都是在编译器这个层次上实现的,在生成的字节码中是不包含泛型中的类型信息的,使用泛型的时候加上类型参数,在编译器编译的时候会去掉,这个过程称为类型擦除。
*/
String s = list.get(0);
}
public static void add(List list, Object o){
list.add(o);//把10作为object填加到list里面是可行的,但是转成String会报 java.lang.ClassCastException
}
五,两个 List 的操作
public static void main(String[] args) {
List<String> alist = new ArrayList<>();
List<String> blist = new ArrayList<>();
alist.add("1");alist.add("2");alist.add("3");
blist.add("2");blist.add("3");blist.add("4");
getAll(alist, blist);
getNoRepeatAll(alist, blist);
getTogether(alist, blist);
getLess(alist, blist);
getOnly();
}
//取并集
public static void getAll(List alist, List blist){
List list = alist;
list.addAll(blist);
System.out.println(list);
}
//取无重复并集
public static void getNoRepeatAll(List alist, List blist){
List list = alist;
list.removeAll(blist);
list.addAll(blist);
System.out.println(list);
}
//取交集
public static void getTogether(List alist, List blist){
List list = alist;
list.retainAll(blist);
System.out.println(list);
}
//差集
public static void getLess(List alist, List blist){
List list = alist;
list.removeAll(blist);
System.out.println(list);
}
//去重复,JDK8新特性
public static void getOnly(){
List<String> list = new ArrayList();
list.add("1");list.add("1");list.add("3");list.add("3");
List newList = (List) list.stream().distinct().collect(Collectors.toList());
System.out.println(newList);
}