【java基础】java基础个人笔记

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转对象

  1. 最常见的转为 List<T>

List<String> strings = JSONObject.parseArray("['yyy','sss']", String.class);
strings.forEach(System.out::print);

  1. 最常见的转为 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);


  1. 转 复杂类型 (比如套娃类型,一个套一个)

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:适用于多线程下在字符串缓冲区进行大量操作。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值