java tricky

MarkLeeBYR / 2023-06-25 / 原文

1、根据枚举的name获取枚举类:

private static SmsProviderType fromName(String spName) {
  return Stream.of(SmsProviderType.values()).filter(sp -> StringUtils.equals(sp.name(), spName)).findFirst().orElse(null);
}

2、字符串转成int(注意给默认值):NumberUtils.toInt

3、collect(Collectors.joining()) 表示把所有字符串连接起来

4、把null转成empty:nullToEmpty()方法

5、joiner.join可以用分隔符把元素连接在一起

6、实体类转为Map形式:
obj -> jsonStr -> map

7、Optional

Optional.ofNullable(...) 入参为null则返回null,否则返回入参
ofNullable(...).ifPresent() 如果ofNullable的结果不是空,则调用ifPresent
Optional.orElse(value) 如果optional保存的是null,返回value。如果保存的不是null,返回option自己的值
Optional.orElseGet(...) 和orElse一样,只是入参是对象
一般从stream中选出个体,就要调用stream的findFirst()方法,然后orElse
firstNonEmpty(T... values)方法,第一个入参不为空则返回 为空则判断后面的 以此类推
isPresent() 返回boolean,如果值存在则方法会返回true,否则返回 false
anyMatch(): stream中任何一个元素满足即返回true
allMatch(): stream中所有元素都满足即返回true
.findAny().isPresent() 和 anyMatch的含义一样

8、forEach和forEachOrder区别:两者完成的功能类似,主要区别在并行处理上,forEachOrdered()将始终按照流(stream)中元素的遇到顺序执行给定的操作,而forEach()方法是不确定的。

9、sorted中可以把Comparator.comparing()的结果作为入参。Comparator.comparing().thenComparing() 可以定义多个排序规则

10、Exception: e.getClass().getSimpleName()可以拿到具体异常的类型

11、Sets.difference(set1, set2) 可以获取元素:在set1中存在但是在set2中不存在。Set的retainAll方法:求交集
12、@RestController注解相当于@ResponseBody + @Controller

13、idea或eclipse的jvm arguments加入 -Dfuck.abc="1234" 在代码中System.getProperty("fuck.abc")可以获取这个值。-D是用来在启动java程序时设置系统属性的
接口中的default方法会被实现类直接继承

14、Random r = new Random() nextInt(bound) 会生成0到bound的值 每次不一样
Random r = new Random(100) 指定种子后,nextInt(bound) 会生成0到bound的值 每次都一样

15、去掉字符串指定的前缀:StringUtils.removeStart(fullNumber, "+")

16、日期转换

localDatetime和毫秒数转化
LocalDateTime end = LocalDateTime.of(2020, 3, 3, 18, 38, 00);
System.out.println(end.toInstant(ZoneOffset.of("+8")).toEpochMilli());

//把yyyy-MM-dd HH:mm:ss转化为Date类型
DateFormat dateFormat2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date myDate2 = dateFormat2.parse("2020-04-25 05:20:01");
System.out.println(myDate2);
System.out.println(myDate2.getTime());

//把Date类型转化为yyyyMMdd字符串

SimpleDateFormat resultFormat = new SimpleDateFormat("yyyyMMdd");
Date date = new Date();
String result = resultFormat.format(date);

17、编码

http的queryString中内容(即?后的内容)和www-form-urlencoded form表单中的内容,经过http请求后会自动被urlEncode编码。urlencode会把/转为%2F,+转为%2B

如果某个字符串需要放入http请求参数中,比如想把某个字符串放在?后, 需要把字符串经过Base64.encodeBase64URLSafeString, 否则会有字符丢失。

Base64非url safe的编码结果,会有+等内容。

Base64.encodeBase64URLSafeString() 方法可以实现+转化为-,/转化为_ 并去掉==。

Base64.encodeBase64URLSafeString()和Base64.encodeBase64String() 生成的字符串 用Base64.decodeBase64() 生成的结果是一样的

对于url safe编码,不管编码多少次,都能用Base64.decodeBase64成功解码

base64编码会让数据扩大1/3

18、IOUtils读取文件

//读取file

String photoPath = "abc";
File photo = new File(photoPath);
byte[] bytes = FileUtils.readFileToByteArray(photo);

//读取inputStream

List<String> words = IOUtils.readLines(ChengYuClickCaptchaTest.class.getResourceAsStream("/words.txt"), "UTF-8")

19、

retrofit2 Response 拿到所有response header:
Headers headersFromResponse = httpRsult.headers();
拿到指定header:
String requestId = String.valueOf(headersFromResponse.get("X-Ca-Request-Id"));

20、retrofit2的http相关注解

@QueryMap Map<String, Integer> map 可传多个参数,都以?形式拼接

如果url中?sig=... @Query("sig") 可传入一个参数对应

@HeaderMap 表示http头部传多个参数

如果@POST("/{indexes}/{type}), @Path("indexes") String indexes 即表示传入参数
@Body 可传入requestBody

21、jdk8 stream

peek: 不能修改流中的元素,只能对元素进行打印输出或者改变引用类型的属性。peek入参是consumer
filter(strategy -> strategy != null) 可用filter(Objects::nonNull)代替

stream代替for循环:IntStream.range(0, 100).forEach()

22、ImageIO生成图片

ImageIO.read可以传入InputStream对象,生成BufferedImage即图片,参考验证码中台ShadowLineamentGeneratorTest
也可以传入file对象

22、查看数据或图片大小:转为byte[]数组,数组长度即代表多少byte,除以1024可得出kb