常犯错误总结(一)

[align=center][size=large]常犯错误总结(一)[/size][/align]

一、Arrays.asList 与 java.util.ArrayList

1.常用代码:

// 将数组转化为集合
int [] intArray = new int[]{1,2,3,4};
List<int[]> asList = Arrays.asList(intArray);


此时 Arrays.asList 转化过程中使用到了一个ArrayList 但此ArrayList 非 java.util.ArrayList 而是 Arrays 内部的一个静态类

2.java.util.Arrays.ArrayList(Arrays的私有内部静态类)
源码分析


// Arrays类中的asList方法
public static <T> List<T> asList(T... a) {
return new ArrayList<T>(a);
}

// 上面的ArrayList 是Arrays 的内部定义的静态类,而非java.util.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) {
if (array==null)
throw new NullPointerException();
a = array;
}
}

// 此ArrayList 继承 AbstractList
// 而AbstractList 实现 List
// 所以 asList 方法可以将 ArrayList 返回给 List
public abstract class AbstractList<E> extends AbstractCollection<E> implements List<E> {
/**
* Sole constructor. (For invocation by subclass constructors, typically
* implicit.)
*/
protected AbstractList() {
}
}


常用方法

// 定义的私有内部静态类支持常用的方法调用,基本等同于java.util.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) {
if (array==null)
throw new NullPointerException();
a = array;
}
// 注意此处的size是数组的个数,而不是数组中元素的格式
// int [] intArray = new int[]{1,2,3,4};
// List<int[]> asList = Arrays.asList(intArray);
// System.out.println(asList.size());
// 输出结果是1而不是4
public int size() {
return a.length;
}

public Object[] toArray() {
return a.clone();
}

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;
}

public E get(int index) {
return a[index];
}

public E set(int index, E element) {
E oldValue = a[index];
a[index] = element;
return oldValue;
}

public int indexOf(Object o) {
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;
}

public boolean contains(Object o) {
return indexOf(o) != -1;
}
}



3.与 java.util.ArrayList 的转化


List<Integer> arrayList = new ArrayList<Integer>(Arrays.asList(integerArray));



4.java.util.Arrays.ArrayList.size()方法


// asList 的参数是 T 泛型,int 是基本数据类型,
// 但 int [] 数组是泛型
int [] intArray = new int[]{1,2,3,4};
List<int[]> asList = Arrays.asList(intArray);
System.out.println(asList.size()); // 1
// asList 的参数是 T ... a ,多个泛型 T
// 而Integer 是引用数据类型,此处被解析为传入了多个参数
Integer [] integerArray = new Integer[]{1,2,3,4};
List<Integer> asList2 = Arrays.asList(integerArray);
System.out.println(asList2);// 4



二、判断集合中是否包含某个元素

1.常用代码

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);


可以改为:

// 因为 java.util.Arrays.ArrayList 有 contain 方法,无需再转为Set
Arrays.asList(arr).contains(targetValue);




for(String s: arr){
if(s.equals(targetValue)) // Objects.equals(s,targetValue)
return true;
}
return false;



三、删除List中的元素

1.三种想法

List<String> listString = new ArrayList<String>(Arrays.asList("a","b","c","d"));
// 删除元素后不会出现异常,但要注意删除元素后原来元素的索引会有变化,比如删除a后,此时b的位置要变为0;此时再想删除b已经不可能了,因为index 已经变为1了。即:删除一个特定元素可以
for(int index = 0 ; index < listString.size() ; index ++){
if("a".equals(listString.get(index))){
listString.remove(index);
}
}

for(String str : listString){
if("a".equals(str)){
listString.remove(str);
}
}

// 使用此方式进行删除
Iterator<String> iterator = listString.iterator();
while(iterator.hasNext()){
if("a".equals(iterator.next())){
iterator.remove();
}
}



博文参考:
[url=http://www.cnblogs.com/pcheng/p/5336903.html]JAVA中循环删除list中元素的方法总结[/url]

四、hashMap 与 hashtable

[url=http://mingyundezuoan.iteye.com/blog/2394239]Hashtable[/url]

hashMap 线程不安全
hashtable 线程安全

五、使用原始类型的集合

集合与集合泛型
即 List 与 List<?> 的区别
在使用过程中,如果未指定具体的泛型实现,在对集合进行增删改操作时会因为类型的

1.代码样例

public class ListMainTest {

public static void add(List list, Object o) {
list.add(o);
}

public static void main(String[] args) {
List<String> list = new ArrayList<String>();
add(list, 10);
String s = list.get(0);
}

}



会抛出异常:
[size=medium][color=red]Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
[/color][/size]

2.异常分析
对 list.get(0) 来说,此时的结果为 Object ,而此时的Object 是通过Integer 类型进行复制的,而接受值的类型却定义为 String ,类型对应错误;

3.总结问题
使用Set<?> 方式在操作时可以起到类型校验的作用,从而避免上述的问题

六、访问权限

编程习惯,通常定义接口或service 时顺手直接public;
按照[url=http://mingyundezuoan.iteye.com/admin/blogs/2397494]编码规范[/url],应该限制用户的访问权限,直接默认即可

七、ArrayList vs. LinkedList

数组;链表
便于查找,而不利于增删改;后者相反;
ArrayList 实现 RandomAccess ,大量数据遍历时使用 for,随机访问;后者,实现 Deque 双向链表,遍历时 使用 Iterator

博文转载:
[url=https://maimai.cn/article/detail?fid=189591735&from=headline&share_user=http%3A%2F%2Fi9.taou.com%2Fmaimai%2Fp%2F3230%2F8953_10_l2khHczjzmz8J4-a160]十个JAVA程序员容易犯的错误[/url]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值