java contains_Java开发人员犯的十大错误,你犯几个?

本篇为译文:

这个列表总结了Java开发人员经常犯的十大错误。

1.将Array转换为ArrayList

若要将数组转换为ArrayList开发人员经常这样做:

List<String> list = Arrays.asList(arr);

Arrays.asList()将返回ArrayList中的私有静态类。Arrays,这不是java.util.ArrayList班级,等级。这个java.util.Arrays.ArrayListset(),get(),contains()方法,但没有任何添加元素的方法,因此其大小是固定的。创造一个真实的ArrayList,你应该做:

ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));

的构造者ArrayList可以接受集合类型,这也是java.util.Arrays.ArrayList.

#2.检查Array是否包含一个值

开发人员经常这样做:

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

代码可以工作,但不需要将列表转换为先设置。将列表转换为集合需要额外的时间。它可以简单到:

Arrays.asList(arr).contains(targetValue);

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

第一个比第二个更易读。

#3.从循环中的列表中删除元素

考虑以下代码,它在迭代期间删除元素:

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]

这种方法存在一个严重的问题。删除元素时,列表的大小会缩小,索引也会发生变化。因此,如果要通过使用索引删除循环中的多个元素,这将无法正常工作。

您可能知道使用迭代器是删除循环中元素的正确方法,而且您知道在Java中foreach循环的工作方式类似于迭代器,但实际上并非如此。考虑以下代码:

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
 
for (String s : list) {
	if (s.equals("a"))
		list.remove(s);
}

它会被扔出去ConcurrentModificationException.

相反,以下内容是可以的:

ArrayList<String> list = new ArrayList<String>(Arrays.asList("a", "b", "c", "d"));
Iterator<String> iter = list.iterator();
while (iter.hasNext()) {
	String s = iter.next();
 
	if (s.equals("a")) {
		iter.remove();
	}
}

.next()必须在此之前调用.remove()..在foreach循环中,编译器将使.next()在移除元素操作后调用,这将导致ConcurrentModificationException..您可能想看看ArrayList.iterator().

#4.Hashtable与HashMap

根据算法中的约定,Hashtable是数据结构的名称。但是在Java中,数据结构的名称是HashMap..其中一个关键的区别是HashtableHashMap那是Hashtable是同步的。所以很多时候你不需要Hashtable,相反HashMap应该用。

HashMap与Treemap vs Hashtable与LinkedHashMap

#5使用原料类型的收藏

在爪哇,原始类型无界通配符类型很容易混合在一起。举个例子,Set是原始类型,而Set<?>是无界通配符类型。

考虑使用原始类型的下列代码List作为参数:

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

此代码将引发异常:

Exception in thread "main" java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
at ...

使用原始类型集合是危险的,因为原始类型集合跳过泛型类型检查,并且不安全。.之间有很大的区别Set,Set<?>,和Set<Object>..检查

原始类型与无界通配符和类型擦除.

#6.访问级别

开发人员经常在类字段中使用public。通过直接引用可以很容易地获得字段值,但这是一个非常糟糕的设计。经验法则是为成员提供尽可能低的访问级别。

公共、默认、受保护和私有的

#7.ArrayList诉LinkedList

当开发人员不知道ArrayListLinkedList,他们经常使用ArrayList因为它看起来很眼熟。然而,它们之间存在着巨大的性能差异。总之,LinkedList如果有大量的添加/删除操作,并且没有很多随机访问操作,则应优先考虑。检查ArrayListv.V.LinkedList来获得更多关于他们的表现的信息,如果这对你来说是新的话。

#8.可变与不可变

不可变对象具有许多优点,如简单性、安全性等。但是它需要为每个不同的值单独设置一个对象,过多的对象可能会导致垃圾收集的成本过高。在可变和不可变之间应该有一个平衡。

通常,可变对象用于避免产生过多的中间对象。一个典型的例子是连接大量的字符串。如果使用不可变字符串,则会立即生成许多符合垃圾回收条件的对象。这浪费了CPU的时间和精力,使用了一个可变的对象-正确的解决方案。StringBuilder).

String result="";
for(String s: arr){
	result = result + s;
}

在其他情况下,可变对象是可取的。例如,将可变对象传递到方法中,可以收集多个结果,而不需要跳过太多的语法圈。另一个例子是排序和过滤:当然,您可以创建一个获取原始集合并返回排序集合的方法,但是对于较大的集合来说,这将变得非常浪费。(来自达斯宾肯莱的回答关于堆栈溢出)

#9.SuperandSub的构造函数

6175ec002835c9615efba687053945c6.png

发生此编译错误是因为默认超级构造函数未定义。在Java中,如果类没有定义构造函数,编译器将在默认情况下为类插入默认的无参数构造函数。如果在Superclass中定义了构造函数,在本例中是Super(String S),编译器将不会插入默认的无参数构造函数。以上是超级班的情况。

子类的构造函数,无论是-参数还是非参数,都将调用无参数超级构造函数。由于编译器试图将Super()插入到Sub类中的2个构造函数,但是没有定义Super默认构造函数,所以编译器会报告错误消息。

要解决这个问题,只需向Superclass添加一个Super()构造函数,如下所示

public Super(){
    System.out.println("Super");
}

,或2)删除自定义的超级构造函数,或3)添加super(value)给分建筑工人。

#10.“还是建筑工人?

字符串可以通过两种方式创建:

//1. use double quotes
String x = "abc";
//2. use constructor
String y = new String("abc");

有什么关系?

下面的例子可以提供一个快速的答案:

String a = "abcd";
String b = "abcd";
System.out.println(a == b);  // True
System.out.println(a.equals(b)); // True
 
String c = new String("abcd");
String d = new String("abcd");
System.out.println(c == d);  // False
System.out.println(c.equals(d)); // True

来源:programcreek

作者未知

原文:Top 10 Mistakes Java Developers Make

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值