目录
1. LocalDateTime1.1 获取时间1.2 字符串转换为时间(LocalDateTime)1.3 LocalDateTime获取毫秒数(东8区,北京时间)1.4 LocalDateTime与Date1.5 另外提示(来自阿里巴巴java开发手册)
2. Lambda表达式的语法2.1 forEach方法2.2 Runnable
3. 数组与集合的转换3.1.集合转数组3.2 数组转集合3.2.1 Arrays.asList()3.2.2 原生方式,拆分数组,添加到List3.2.3 Collections.addAll()3.2.4 List.of()
3.3 题外话
4. Json 与 对象 转换4.1 json转对象4.2 对象转json
5. String、StringBuffer和StringBuilder5.1 CharSequence接口5.2 运算速度5.3 线程安全性5.4 总结
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
);
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
public static LocalDateTime
convertDateToLDT(Date date
) {
return LocalDateTime
.ofInstant(date
.toInstant(), ZoneId
.systemDefault());
}
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
@Test
public void runnableTest(){
Runnable r
= new Runnable() {
@Override
public void run() {
System
.out
.println("emmmm");
}
};
Thread t
= new Thread(r
);
t
.start();
}
@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:适用于多线程下在字符串缓冲区进行大量操作。