目录
1. LocalDateTime
Java8推出的三个时间类型:LocalDateTime;LocalDate;LocalTime。
1.1 获取时间
//获取当前时间
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime time = LocalDateTime.now();
String mon = df.format(time);
System.out.println(mon);
//2019-04-17 15:49:00
/*
可以跑一下这注释代码
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime time = LocalDateTime.now().plusMonths(-2).plusDays(-1);
String mon = df.format(time);
System.out.println(mon);
*/
1.2 字符串转换为时间(LocalDateTime)
//字符串转时间
String dateTimeStr = "9102-01-01 01:01:01";
DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime dateTime = LocalDateTime.parse(dateTimeStr, df);
System.out.println(dateTime);
控制台结果:
9102-01-01T01:01:01
1.3 LocalDateTime获取毫秒数(东8区,北京时间)
//获取秒数
Long second = LocalDateTime.now().toEpochSecond(ZoneOffset.of("+8"));
//获取毫秒数
Long milliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
1.4 LocalDateTime与Date
//Date转换为LocalDateTime
public static LocalDateTime convertDateToLDT(Date date) {
return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());
}
//LocalDateTime转换为Date
public static Date convertLDTToDate(LocalDateTime time) {
return Date.from(time.atZone(ZoneId.systemDefault()).toInstant());
}
公司一般都有自己独有的工具类。
1.5 另外提示(来自阿里巴巴java开发手册)
SimpleDateFormat 是线程不安全的类,一般不要定义为 static 变量,如果定义为static,必须加锁,或者使用 DateUtils 工具类。
正例:注意线程安全,使用 DateUtils。亦推荐如下处理:
private static final ThreadLocal<DateFormat> df = new ThreadLocal<DateFormat>() {
@Override
protected DateFormat initialValue() {
return new SimpleDateFormat("yyyy-MM-dd");
}
};
说明:如果是 JDK8 的应用,可以使用 Instant 代替 Date,LocalDateTime 代替 Calendar,
DateTimeFormatter 代替 SimpleDateFormat,
官方给出的解释:simple beautiful strong immutable thread-safe。
直接将以前做的笔记复制过来了
有错误之处,望指出
我没有整合过LocalDateTime的工具类,因为我公司一直都是用Date
2. Lambda表达式的语法
基本语法: (parameters) -> expression 或 (parameters) ->{ statements; }
2.1 forEach方法
@Test
public void linkedHashMapTest(){
LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
map.put("111","111");
map.put("444","444");
map.put("222","222");
map.put("333","333");
map.keySet().forEach(a -> System.out.println(map.get(a)));
}
//打印
111
444
222
333
@Test
public void listTest(){
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
numbers.forEach(System.out::print);
}
//打印
12345
2.2 Runnable
//不使用 Lambda 表达式
@Test
public void runnableTest(){
Runnable r = new Runnable() {
@Override
public void run() {
System.out.println("emmmm");
}
};
Thread t = new Thread(r);
t.start();
}
//使用 Lambda 表达式
@Test
public void runnableTest(){
Runnable r = () ->{
System.out.println("emmmm");
};
Thread t = new Thread(r);
t.start();
}
//或者
@Test
public void runnableTest(){
Thread t = new Thread(() -> {
System.out.println("emmmm");
});
t.start;
}
3. 数组与集合的转换
资源来自阿里云的编程约束
仅供参考
3.1.集合转数组
使用集合转数组的方法,必须使用集合的 toArray(T[] array),传入的是类型完全一样的数组,大小就是 list.size()。
说明:使用 toArray 带参方法,入参分配的数组空间不够大时,toArray 方法内部将重新分配内存空间,并返回新数组地址;如果数组元素大于实际> 所需,下标为[ list.size() ]的数组元素将被置为 null,其它数组元素保持原值,因此最好将方法入参数组大小定义与集合元素个数一致。
正例:
List<String> list = new ArrayList<String>(2);
list.add("guan");
list.add("bao");
String[] array = new String[list.size()];
array = list.toArray(array);
反例:直接使用 toArray 无参方法存在问题,此方法返回值只能是 Object[]类,若强转其它
类型数组将出现 ClassCastException 错误。
3.2 数组转集合
3.2.1 Arrays.asList()
使用工具类 Arrays.asList()把数组转换成集合时,不能使用其修改集合相关的方法,它的 add/remove/clear 方法会抛出 UnsupportedOperationException 异常。
说明:asList 的返回对象是一个 Arrays 内部类,并没有实现集合的修改方法。Arrays.asList体现的是适配器模式,只是转换接口,后台的数据仍是数组。
String[] str = new String[] { "you", "wu" };
List list = Arrays.asList(str);
第一种情况:list.add(“yangguanbao”); 运行时异常。
第二种情况:str[0] = “gujin”; 那么 list.get(0)也会随之修改。
3.2.2 原生方式,拆分数组,添加到List
(在项目中,使用原生的就可以了)
List<String> resultList = new ArrayList<>(array.length);
for (String s : array) {
resultList.add(s);
}
3.2.3 Collections.addAll()
(在项目中,使用这个也可以)
List<String> resultList = new ArrayList<>(array.length);
Collections.addAll(resultList,array);
3.2.4 List.of()
此方法为 Java9新增方法,定义在List接口内,并且为静态方法,故可以由类名直接调用。
List<String> resultList = List.of(array);
3.3 题外话
ArrayList的subList结果不可强转成ArrayList,否则会抛出ClassCastException异常,即 java.util.RandomAccessSubList cannot be cast to java.util.ArrayList.
说明:subList 返回的是 ArrayList 的内部类 SubList,并不是 ArrayList ,而是ArrayList
的一个视图,对于 SubList 子列表的所有操作最终会反映到原列表上。
4. Json 与 对象 转换
我使用的是 马哥的fastjson(谷歌的Gson,和Spring自带的Json工具都比较好)
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.12</version>
</dependency>
4.1 json转对象
- 最常见的转为 List<T>
List<String> strings = JSONObject.parseArray("['yyy','sss']", String.class);
strings.forEach(System.out::print);
- 最常见的转为 Object
String ds = "{\"111\":\"111\",\"444\":\"444\",\"222\":\"222\",\"333\":\"333\"}";
LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
map = JSONObject.parseObject(ds,LinkedHashMap.class);
- 转 复杂类型 (比如套娃类型,一个套一个)
String ds = "{\"111\":\"111\",\"444\":\"444\",\"222\":\"222\",\"333\":\"333\"}";
LinkedHashMap<String,String> map = JSONObject.parseObject(ds,new TypeReference<LinkedHashMap<String,String>>(){});
map.keySet().forEach(a -> System.out.println(map.get(a)));
4.2 对象转json
LinkedHashMap<String,String> map = new LinkedHashMap<String,String>();
map.put("111","111");
map.put("444","444");
map.put("222","222");
map.put("333","333");
String s = JSON.toJSONString(map);
System.out.println(s);
5. String、StringBuffer和StringBuilder
5.1 CharSequence接口
String、StringBuffer和StringBuilder 都实现 CharSequence接口
在JDK1.4中,引入了CharSequence接口,实现了这个接口的类有:CharBuffer、String、StringBuffer、StringBuilder这个四个类。
5.2 运算速度
通常情况下:StringBuilder > StringBuffer > String
如下的代码写法形式速度会很慢,JVM会不断地创建和回收对象来进行操作。
String str1 = "abc";
String str2 = "de";
String str = str1 + str2;
5.3 线程安全性
StringBuilder(非线程安全)
而StringBuilder的方法没有该关键字修饰,所以不能保证线程安全性。是JDK1.5新增的,该类提供一个与StringBuffer兼容的API,但不能保证同步,所以在性能上较高。该类被设计用作 StringBuffer的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能,建议优先采用该类,因为在大多数实现中,它比StringBuffer 要快。两者的方法基本相同。
StringBuffer(线程安全的)
StringBuffer中大部分方法由synchronized关键字修饰,在必要时可对方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致,所以是线程安全的。类似于String的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。StringBuffer上的主要操作是 append 和 insert方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。append方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
5.4 总结
String:适用于少量的字符串操作。
StringBuilder:适用于单线程下在字符串缓冲区进行大量操作。
StringBuffer:适用于多线程下在字符串缓冲区进行大量操作。