最近在看阿里开发手册,稍微总结几个有用的。
1 使用Objects的equals方法
除了Object类,还有一个Objects的类,他们的区别:
- Object 是 Java 中所有类的基类,位于java.lang包。
- Objects 是 Object 的工具类,位于java.util包。jdk1.7引入的工具类,被final修饰不能被继承,拥有私有的构造函数。它由一些静态的实用方法组成,这些方法是
null-save
(空指针安全的)或null-tolerant
(容忍空指针的),用于计算对象的hashcode
、返回对象的字符串表示形式、比较两个对象。
这两个类中的equals方法:
-
在比较两个对象的时候,
Object.equals
方法容易抛出空指针异常。不会出现问题: String s = null; System.out.println("a".equals(s)); 出现问题: System.out.println(s.equals("a"));
它就会报一个空指针异常 ,所以使用Object中的equals方法时应使用常量或确定有值的对象来调用equals方法,如 “a”.equals(s)
但要注意的是如果是两个变量比较的时候,都需要加非空判断。
-
再来看看
Objecs
中的equals
方法
Objects.equals方法中已经做了非空判断,所以不会抛出空指针异常,它是null-save空指针安全的,而且也可以简化代码。源码如下:public static boolean equals(Object a, Object b) { return (a == b) || (a != null && a.equals(b)); }
实际运用:
String s = null; System.out.println(Objects.equals(s, "hello"));
用这种方法,就算是比较两个对象也不需要我们自己来做非空判断了。
2 禁止使用 BigDecimal 的构造方法方式把double 值转化对象。
优先推荐入参为String 的构造方法,或使用BigDecimal 的valueOf 方法,此方法内部其实执行了Double
的toString
,而Double
的toString
按double
的实际能表达的精度对尾数进行了截断。
BigDecimal recommend1 = new BigDecimal("0.1");
BigDecimal recommend2 = BigDecimal.valueOf(0.1);
3 关于日期
日期格式化时:
yyyy
表示当天所在的年- 大写的
YYYY
代表是week in which year(JDK7 之后引入的概念),意思是当天所在的周属于的年份,一周从周日开始,周六结束,只要本周跨年,返回的YYYY
就是下一年。 - 表示
月份
是大写的M
; - 表示
分钟
则是小写的m
; 24 小时制
的是大写的H
;12 小时制
的则是小写的h
。
获取当前毫秒数:System.currentTimeMillis()
; 而不是new Date().getTime()
。
不要在程序中写死一年为365 天:
// 获取今年的天数
int daysOfThisYear = LocalDate.now().lengthOfYear();
// 获取指定某年的天数
LocalDate.of(2011, 1, 1).lengthOfYear();
4 判断元素是否为空
队列:
- 导入jar包为
import org.apache.commons.lang3.ArrayUtils;
ArrayUtils.isNotEmpty()
- 或者
XX.isEmpty()
字符串:
- 导入jar包为
import org.apache.commons.lang3.StringUtils;
StringUtils.isNotBlank()
是否不为空,多个空格也算是空isNotEmpty
空格不算是空isNoneBlank
可以放多个,或者数组、队列isNoneEmpty
5 集合处理
使用 Collectors.toMap()
在使用java.util.stream.Collectors
类的toMap()方法转为Map 集合时,一定要使用含有参数类型为BinaryOperator,参数名为mergeFunction 的方法,否则当出现相同key值时会抛出IllegalStateException 异常。
并且要注意如果value
为null,那么也会抛出异常
List<Pair<String, Double>> pairList = new ArrayList<>(3);
pairList.add(new Pair<>("version", 6.9));
pairList.add(new Pair<>("version", 13.14));
pairList.add(new Pair<>("version", 10.24));
Map<String, Double> collect = pairList.stream().collect(Collectors.toMap(Pair::getKey, Pair::getValue, (aDouble1, aDouble2) -> aDouble1));
System.out.println(collect);
String[] departments = new String[] {"iERP", "iERP", "EIBU"};
Map<Integer, String> map2 = Arrays.stream(departments)
.collect(Collectors.toMap(String::hashCode, String::toString, (s, s2) -> s2));
System.out.println(map2);
结果:
{version=6.9}
{2127863=EIBU, 3196986=iERP}
XX.subList()
subList 返回的是ArrayList 的内部类SubList,并不是 ArrayList 而是ArrayList 的一个视图,对于SubList 子列表的所有操作最终会反映到原列表上。
ArrayList q = new ArrayList();
q.add(1);
q.add(2);
q.add(3);
q.add(4);
List list = q.subList(1, 2);
list.set(0,111);
System.out.println(q);
System.out.println(list);
结果:
[1, 111, 3, 4]
[111]
集合初始化时指定大小:
initialCapacity = (需要存储的元素个数 / 负载因子) + 1。注意负载因子(即loader factor)默认为0.75,如果暂时无法确定初始值大小,请设置为16(即默认值)。
使用entrySet 遍历Map类集合KV,而不是keySet 方式进行遍历
Map 类集合K/V 能不能存储null 值的情况
集合类 | Key | Value | Super | 说明 |
---|---|---|---|---|
Hashtable | 不允许为null | 不允许为null | Dictionary | 线程安全 |
ConcurrentHashMap | 不允许为null | 不允许为null | AbstractMap | 锁分段技术(JDK8:CAS) |
TreeMap | 不允许为null | 允许为null | AbstractMap | 线程不安全 |
HashMap | 允许为null | 允许为null | AbstractMap | 线程不安全 |
使用LocalDateTime 和DateTimeFormatter
如果是JDK8 的应用,可以使用Instant 代替Date,LocalDateTime 代替Calendar,DateTimeFormatter 代替SimpleDateFormat
如果不太会用可以看看这个兄弟发的文章,我觉得挺好的。
Instant now = Instant.now();
LocalDateTime now1 = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String format = dateTimeFormatter.format(now1);
System.out.println(format);
其他:
找到一个好玩的东西,Cglib 的 BeanCopier
,经过测试发现要比BeanUtils的要快。
Student student = new Student ();
student.setId(1);
student.setName("小寒");
BeanCopier copier = BeanCopier.create(Student.class, StudentVo.class, false);
StudentVo studentVo = new StudentVo();
copier.copy(student , studentVo , null);
System.out.println(student);
System.out.println(studentVo);
结果:
student{id=1, name='orderName'}
studentVo{idVO=0, name='orderName'}