1.String 相等

稍微有点经验的程序员都会用equals比较而不是用 ==,但用equals就真的安全了吗,看下面的代码

user.getName().equals("xiaoming");

有经验的老司机很快就能看到问题,如果user.getName()为null,就会抛出空指针异常,因此下面的写法更为稳妥

"xiaoming".equals(user.getName());

当然这种写法并不是万能的,如果比对的两边都是未知变量,如下

user.getName().equals(user1.getName());//user.getName() 和 user1.getName()都有可能为null

因此更为稳妥的方法可以采用jdk Objects类中的equals方法,左右两边都可以避免空指针异常

Objects.equals(user.getName(), user1.getName());

需要注意的是Objects类在jdk1.7才支持,如果是jdk1.6,可以采用guava中的Objects类代替

2.Integer 比较

Integer a = 127;
Integer b = 127;
Integer c = 128;
Integer d = 128;
System.out.println(a == b);// 结果为:true
System.out.println(c == d);// 结果为:false

令人惊讶的是结果并不是预料中的全是true,而是一个为true,一个为false

至于原因还需要从源码中探究

首先通过源码来看一下,当通过 = 对Integer赋值时,实际调用了Integer.valueOf()方法

public static Integer valueOf(int i) {
assert IntegerCache.high >= 127;
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

可以看到当 i >= IntegerCache.low && i <= IntegerCache.high 时,是从一个缓存类中取,其它情况会new一个对象。IntegerCache.low默认为-128,high默认为127(可调整)。

这样a=b就很好解释了,因为==比较的是内存地址,a,b都是从这个缓存类中取的同一个对象,所以返回结果为true。b,c则都是new的新对象,内存地址自然不同,所以返回false

既然看到了这个缓存类,就有必要一睹它的庐山真面目了

private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[]; static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
} private IntegerCache() {}
}

IntegerCache 是Integer类中一个静态内部类,high值可通过JVM 的启动参数设置

3.Arrays.asList(array)

String [] array= {"a","b","c"};
// 返回的List实例为:java.util.Arrays.ArrayList
List<String> list = Arrays.asList(array);
list.remove(0);

Arrays.asList是一种很常见的创建List的方式,但该方法返回的List实例不是平时常用的List实例,而是Arrays的一个静态内部类,该类继承自AbstractList类,并为提供List的完整的实现,例如remove方法就未实现,当然,如果只是用做遍历,则完全是没问题的

类似的情况还有不少,使用时要注意,例如:

  1. ArrayList的subList方法,返回的是ArrayList中的一个内部类java.util.ArrayList.SubList
  2. HashMap的values方法,返回的是HashMap中的一个内部类:java.util.HashMap.Values

4.list.toArray

List<String> list = new ArrayList<String>();
String[] array=(String[]) list.toArray();

上面的写法乍一看似乎没有什么问题,但list.toArray()返回的是一个object数组,强转会抛异常。其实是可以指定返回数组的类型的,如下

String[] array=list.toArray(new String[list.size()]);

5.foreach remove

List<String> list =new ArrayList<String>();
list.add("java");
list.add("c");
list.add("js");
for(String str:list){
list.remove(0);
}

在遍历时删除元素也是比较常用的操作,但foreach时删除元素有可能抛异常,这种不好控制的写法还是不用为好,可以用迭代器去代替

for (Iterator<String> iterator = list.iterator(); iterator.hasNext();) {
String str = iterator.next();
iterator.remove();
}

6. String getBytes

String str="韦德";
byte[] bytes = str.getBytes();

String的getBytes()方法用的是当前项目的默认编码,如果不指定编码,在不同的运行环境很容易被坑,所以还是根据自己的需要指定对应的编码比较靠谱

String str="韦德";
byte[] bytes = str.getBytes("utf-8");

java踩坑记的更多相关文章

  1. mongo java 踩坑记

    为什么会有这么多坑 1.  Java会把 id:String = "合法ObjectId"  好心好意的 转为  _id:ObjectId 类型. 2. 为了避免第1点, 我定义了 ...

  2. Java踩坑记系列之Arrays.AsList

    java.util.Arrays的asList方法可以方便的将数组转化为集合,我们平时开发在初始化ArrayList时使用的比较多,可以简化代码,但这个静态方法asList()有几个坑需要注意: 一. ...

  3. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  4. Spark踩坑记——数据库(Hbase+Mysql)

    [TOC] 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库,去统计或者改变一些值.最近一个实时消费者处理任务,在使用spark streami ...

  5. 【踩坑记】从HybridApp到ReactNative

    前言 随着移动互联网的兴起,Webapp开始大行其道.大概在15年下半年的时候我接触到了HybridApp.因为当时还没毕业嘛,所以并不清楚自己未来的方向,所以就投入了HybridApp的怀抱. Hy ...

  6. Spark踩坑记——共享变量

    [TOC] 前言 Spark踩坑记--初试 Spark踩坑记--数据库(Hbase+Mysql) Spark踩坑记--Spark Streaming+kafka应用及调优 在前面总结的几篇spark踩 ...

  7. Spark踩坑记——从RDD看集群调度

    [TOC] 前言 在Spark的使用中,性能的调优配置过程中,查阅了很多资料,之前自己总结过两篇小博文Spark踩坑记--初试和Spark踩坑记--数据库(Hbase+Mysql),第一篇概况的归纳了 ...

  8. [转]Spark 踩坑记:数据库(Hbase+Mysql)

    https://cloud.tencent.com/developer/article/1004820 Spark 踩坑记:数据库(Hbase+Mysql) 前言 在使用Spark Streaming ...

  9. Spark踩坑记——数据库(Hbase+Mysql)转

    转自:http://www.cnblogs.com/xlturing/p/spark.html 前言 在使用Spark Streaming的过程中对于计算产生结果的进行持久化时,我们往往需要操作数据库 ...

随机推荐

  1. Java数组笔记

    # 数组--------内存 # 2017/8/31 15:29:19  ## 数组(容器) ## - 为了存储同种数据类型的多个值 - 概念     - 数组是可以存储同一种数据类型多个元素的集合, ...

  2. 入侵拿下DVBBS php官网详细过程(图)

    几 个月前,DVBBS php2.0暴了一个可以直接读出管理员密码的sql注入漏洞,当时这个漏洞出来的时候,我看的心痒,怎么还会有这么弱智的漏洞,DVBBS php2.0这套代码我还没仔细看过,于是5 ...

  3. JavaScript封装一个实用的select控件

    最近一直把精力放在项目上面,导致忽略的一些底层的东西.以前就一直觉得原有的select控件很丑,正好周末有时间,试着做了一个简单封装,实现了它的基本功能.我总结了一下,大概分为三个部分: 1.对显示样 ...

  4. web站点优化之使用tengine搭建静态资源服务器,静态资源合并加载案例剖析

    在一个项目还是单体架构的时候,所有的js,css,image都会在一个web网站上,看起来并没有什么问题,比如下面这样: 但是当web网站流量起来的时候,这个单体架构必须要进行横向扩展,而在原来的架构 ...

  5. Partition函数

    快排中核心的方法应该算是Partition函数了,它的作用就是将整个数组分成小于基准值的左边,和大于基准值的右边. 普通的Partition函数是这样的: public static int part ...

  6. Markdown最佳实践

    Markdown 最佳实践 结合目前看到的信息,总结使用Markdown的最方便的方式. 我的需求是: 能够配合各种笔记软件使用,目前主要使用的是为知笔记和有道笔记.笔记的内容需要记录代码及数学公式, ...

  7. SpringMVC入门第二天

    SpringMVC第二天 1.   回顾 1.Springmvc介绍? Springmvc是Spring公司 2.Springmvc入门程序 第一步:Web工程 第二步:导Jar包 第三步:web.x ...

  8. Java Spring的简单见解

    Spring的注解特性,IOC控制反转 首先了解依赖注入是什么,就是在实例化对象的时候并不需要每次都new对象出来,spring管理对象,在你配置been或者@service时候 Spring会自动帮 ...

  9. ButterKnife的安装与使用以及ButterKnife右键不显示的大坑

    作为从安卓的的入门选手,第一次看到还以为是个第三方呢,从github下来之后感觉不对啊,这么多东西,后来一搜原来是个插件,而且不用从github上下载. 安装的方法很简单. 第一步:打开安卓studi ...

  10. 团队作业9--测试与发布(Beta版)

    Beta版本测试报告 1.在测试过程中总共发现了多少Bug?每个类别的Bug分别为多少个? a. 修复的bug: 写入SD存储卡文件权限问题 页面正确跳转 及 部分页面闪退的问题 b. 不能重现的bu ...