点击上方“Github爱好者社区”,选择星标
回复“资料”,获取小编整理的一份资料
原文:http://www.programcreek.com/2014/05/top-10-mistakes-java-developers-make/
译文:cnblogs.com/chenpi/p/5508949.html
Array转ArrayList
判断一个数组是否包含某个值
在循环内部删除List中的一个元素
HashTable与HashMap
使用集合原始类型(raw type)
访问级别
ArrayList和LinkedList
可变与不可变
父类和子类的构造方法
“”还是构造方法
未来工作
这个列表总结了10个Java开发人员最常犯的错误。
当需要把Array转成ArrayList的时候,开发人员经常这样做:
List<String> list = Arrays.asList(arr);
Arrays.asList()会返回一个ArrayList,但是要特别注意,这个ArrayList是Arrays类的静态内部类,并不是java.util.ArrayList类。
java.util.Arrays.ArrayList类实现了set(), get(),contains()方法,但是并没有实现增加元素的方法(事实上是可以调用add方法,但是没有具体实现,仅仅抛出UnsupportedOperationException异常),因此它的大小也是固定不变的。为了创建一个真正的java.util.ArrayList,你应该这样做:
ArrayList<String> arrayList = new ArrayList<String>(Arrays.asList(arr));
ArrayList的构造方法可以接收一个Collection类型,而java.util.Arrays.ArrayList已经实现了该接口。
开发人员经常这样做:
Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);
以上代码可以正常工作,但是没有必要将其转换成set集合,将一个List转成Set需要额外的时间,其实我们可以简单的使用如下方法即可:
Arrays.asList(arr).contains(targetValue);
或者
for(String s: arr){
if(s.equals(targetValue))
return true;
}
return false;
第一种方法可读性更强。
考虑如下代码,在迭代期间删除元素:
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]
在上面这个方法中有一系列的问题,当一个元素被删除的时候,list大小减小,然后原先索引指向了其它元素。所以如果你想在循环里通过索引来删除多个元素,将不会正确工作。
你也许知道使用迭代器是在循环里删除元素的正确方式,或许你也知道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异常。
然而接下来的代码却是OK的:
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()的源码。
从算法的角度来讲,HashTable是一种数据结构名称。但是在Java中,这种数据结构叫做HashMap。
HashTable与HashMap的一个主要的区别是HashTable是同步的,所以,通常来说,你会使用HashMap,而不是Hashtable。
在Java中,原始类型(raw type)和无界通配符类型很容易让人混淆。举个Set的例子,Set是原始类型,而Set是无界通配符类型。
请看如下代码,add方法使用了一个原始类型的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这三个有很大的不同。
开发人员经常使用public修饰类字段,虽然这很容易让别人直接通过引用获取该字段的值,但这是一个不好的设计。根据经验,应该尽可能的降低成员属性的访问级别。
为什么开发人员经常使用ArrayList和LinkedList,却不知道他们之间的区别,因为它们看起来很像。然而它们之间有着巨大的性能差异。简单的说,如果有大量的增加删除操作并且没有很多的随机访问元素的操作,应该首选LinkedList。
不可变对象有很多优点,如简单、安全等。但是对于每个不同的值都需要一个单独的对象,太多的对象会引起大量垃圾回收,因此在选择可变与不可变的时候,需要有一个平衡。
通常,可变对象用于避免产生大量的中间对象,一个经典的例子是大量字符串的拼接。如果你使用一个不可变对象,将会马上产生大量符合垃圾回收标准的对象,这浪费了CPU大量的时间和精力。使用可变对象是正确的解决方案(StringBuilder);
String result="";
for(String s: arr){
result = result + s;
}
另外,在有些其它情况下也是需要使用可变对象。例如往一个方法传入一个可变对象,然后收集多种结果,而不需要写太多的语法。另一个例子是排序和过滤:当然,你可以写一个方法来接收原始的集合,并且返回一个排好序的集合,但是那样对于大的集合就太浪费了。
之所以出现这个编译错误,是因为父类的默认构造方法未定义。在Java中,如果一个类没有定义构造方法,编译器会默认插入一个无参数的构造方法;但是如果一个构造方法在父类中已定义,在这种情况,编译器是不会自动插入一个默认的无参构造方法,这正是以上demo的情况;
对于子类来说,不管是无参构造方法还是有参构造方法,都会默认调用父类的无参构造方法;当编译器尝试在子类中往这两个构造方法插入super()方法时,因为父类没有一个默认的无参构造方法,所以编译器报错;
1、在父类手动定义一个无参构造方法:
public Super(){
System.out.println("Super");
}
2、移除父类中自定义的构造方法
3、在子类中自己写上父类构造方法的调用;如super(value);
有两种创建字符串的方式:
//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
更多关于它们内存分配的信息,请参考Create Java String Using ” ” or Constructor??
这个列表是我基于大量的github上的开源项目,Stack overflow上的问题,还有一些流行的google搜索的分析。没有明显示的评估证明它们是前10,但它们绝对是很常见的。
如果您不同意任一部分,请留下您的评论。如果您能提出其它一些常见的错误,我将会非常感激。
好啦,今天的分享就到这儿啦,我们下次见啦~
GitHub原创推荐• 牛逼了!DeepFake变脸再次来袭,强势霸屏GitHub热榜!偏门应用“美女脱衣”还会再出现么?• 卧槽!还有这种事!马斯克的SpaceX-API 竟然开源了!登顶GitHub热榜!• 牛!Google 开源的这份工程实践,GitHub标星14.4k,果然大厂出品,必是精品!关注「Github爱好者社区」加星标,每天带你逛Github好玩的项目
文章浏览阅读370次,点赞2次,收藏3次。【代码】css3卡片前后无限循环翻转效果。_卡片翻动效果
文章浏览阅读1.1k次,点赞10次,收藏11次。pstree是一个Linux命令,它以树状图的形式显示运行中的进程。这种树状图的格式比ps命令更直观,使输出更具视觉吸引力。_linux 安装pstree
文章浏览阅读2.7k次。linux关机重启六种方法(sysrq shutdown halt init ipmi poweroff)我的博客已迁移到xdoujiang.com请去那边和我交流linux关机重启六种方法(sysrqshutdownhaltinit)当前版本cat/etc/debian_version5.0.1一、linux关机命令(前四种)1、shutdown-hnow(-h:haltafter..._linux poweroff关机失败,poweroff -f关机成功
文章浏览阅读7.8k次,点赞6次,收藏11次。作为一名IT民工来说,对于电脑的各种操作都需要熟练掌握,不仅要学会Windows电脑的操作,更要学会Mac电脑的操作,不同的操作系统,有些操作是不一样的,就拿终端命令行来说,Windows系统的cmd和Mac系统自带的终端就不一样。 由于觉得Windows系统的cmd命令工具用着不习惯,所以本篇博文只来分享一下Mac电脑系统下自带的终端的关于管理员用户的切换方法,这个知识点虽然比较..._mac 终端切换交互方式
文章浏览阅读3.3k次,点赞4次,收藏10次。他说按我的操作步骤,到开启Root的步骤后,无论如何也下载不下来Root安装包,导致无法获取Root权限。从我的小米5手机Root成功,到现在才一个来月,难道小米官方就关闭了此型号的Root服务,彻底把这枚钉子户抛弃了?下载一个刷机包->下载并安装magisk->用magic修改刷机包->将刷机包刷入手机->测试成功->舔杯(只是阶段性的胜利,不能大张旗鼓的干杯)备份手机数据-->解锁BL-->刷开发版-->开启Root-->安装文件管理器-->替换相关文件-->测试-->干杯!下面是一些我的维修故事。_小米5电信卡不能打电话
文章浏览阅读539次。[java] view plain copytextview.getPaint().setFlags(Paint. STRIKE_THRU_TEXT_FLAG ); //中间横线 [java] view plain copytextview.getPaint().setFlags(Paint.UNDERLINE__android textview paint 添加中横线
文章浏览阅读2.1k次,点赞104次,收藏87次。HTML5和CSS3-19(20)-1(3)
文章浏览阅读1.4w次,点赞20次,收藏91次。目录1.引言:一些基本概念,2.为什么要进行归一化?归一化两个的优点3.为什么要标准化?标准化的好处?4.归一化和标准化的区别5.什么时候用归一化?什么时候用标准化?6. 哪些模型必须归一化/标准化?7、逻辑回归必须要进行标准化吗?8. 为什么需要批归一化(BN)?9. BN的好处10、BN的原理11、BN到底解决了什么Reference:..._组均值和总均值中心化
文章浏览阅读1.8w次,点赞20次,收藏189次。官方文档地址:DataV1.安装组件库npm安装 npm install @jiaminghi/data-view 2.使用 全局引入// 将自动注册所有组件为全局组件import dataV from '@jiaminghi/data-view'Vue.use(dataV)按需引入按需引入仅支持基于ES module的tree shaking,按需引入示例如下:import { borderBox1 } from '@jiaminghi/data-view'V_datav大屏
文章浏览阅读2.8w次,点赞31次,收藏407次。一、引言 LSTM出现以来,在捕获时间序列依赖关系方面表现出了强大的潜力,直到Transformer的大杀四方。但是,就像我在上一篇博客《RNN与LSTM原理浅析》末尾提到的一样,虽然Transformer在目标检测、目标识别、时间序列预测等各领域都有着优于传统模型的表现,甚至是压倒性的优势。但Transformer所依赖的Multi-Head Attention机制给模型带来了巨大的参数量与计算开销,这使得模型难以满足实时性要求高的任务需求。我也提到,LSTM想与Transformer抗..._时间注意力机制
文章浏览阅读145次。在越来越多的人询问零件生产技术后,Saffron Electrical&Power开始探索3D打印的优势。Safran Electrical&Power采用增材技术和系统,与Betatype合作,利用其在3D打印技术和DfAM方面的专业知识。正如Safran Electrical&Power的Mark Craig所解释的那样:..._3d打印 电池部件结构
文章浏览阅读580次。魅族号称耗费了很长时间打造的魅族17终于发布了,搭载高通的高端芯片骁龙865,定价高达3699元起,看起来比小米10便宜了300元,然而别忘记了如今小米主打性价比的是红米品牌,而同样搭载...