Java实用技术点
获取项目根目录和系统分隔符
Java如何获得平台相关的行分隔符、路径分隔符?
springboot获取项目的绝对路径和根目录
springboot获取项目目录路径的方法
java获取根目录
获取日期时间
@Test
public void test() {
// 时间戳
long timeMillis = System.currentTimeMillis();
System.out.println(timeMillis);
// 纳米时间戳
long nanoTime = System.nanoTime();
long milliseconds = nanoTime / 1000000;
System.out.println(nanoTime);
System.out.println(milliseconds);
// 获取本地时间
LocalDateTime now = LocalDateTime.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("ssSSS");
String formatted = now.format(formatter);
System.out.println(formatted);
int time1 = Integer.parseInt(formatted.substring(2));
System.out.println(time1);
// Date
Date date = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
System.out.println(sdf.format(date));
long time2 = date.getTime();
System.out.println(time2);
// Calendar
Calendar instance = Calendar.getInstance();
System.out.println(sdf.format(instance.getTime()));
// 获取年月日时分秒
int y = instance.get(Calendar.YEAR);
int month = instance.get(Calendar.MONTH)+1;
int day = instance.get(Calendar.DATE);
int hour = instance.get(Calendar.HOUR_OF_DAY);
int min = instance.get(Calendar.MINUTE);
int se = instance.get(Calendar.SECOND);
System.out.println(y + "-" + month + "-" + day + " " + hour + ":" + min + ":" + se);
}
Java输出多位小数
方法一:String类的方式
方法二:printf格式化输出
方法三:DecimalFormat类的方式
参考:
Java输出多位小数(三种方法)
判断字符串是否是数字
参考:
Java中判断字符串是否为数字的五种方法
Java判断字符串是否为数字
java算法----判断字符串是否为数值型字符串
matcher.group()用法
字符串拼接
- 使用 “+” 运算符拼接字符串
- 使用 StringBuilder 或 StringBuffer 类
- 使用StringJoiner类
- 使用String类join方法
- 使用StringUtils类
- 使用String类concat方法
- 使用 String.format() 方法格式化字符串
- 使用 Stream实现
@Test
public void test() {
// + 号拼接略
// stringbuffer / stringbuilder 拼接 -- 避免创建大量的字符串对象,从而提高性能
StringBuffer hello = new StringBuffer("hello");
StringBuffer append = hello.append(" ").append("world");
System.out.println(append.toString());
// 使用StringJoiner类
StringJoiner stringJoiner = new StringJoiner(",");
stringJoiner.add("hello"); stringJoiner.add("world");
System.out.println(stringJoiner.toString());
StringJoiner stringJoiner1 = new StringJoiner(" ", "[", "]");
stringJoiner1.add("we"); stringJoiner1.add("are"); stringJoiner1.add("friends");
System.out.println(stringJoiner1.toString());
// 使用String类join方法
String[] arr = new String[]{"hello", "world", "we", "are", "friends"};
String join = String.join(", ", arr);
System.out.println(join);
// 使用StringUtils类
String join1 = StringUtils.join(Arrays.asList(arr), "-");
System.out.println(join1);
// 使用String类concat方法
String concat = "hello".concat(" ").concat("world");
System.out.println(concat);
// 使用 String.format() 方法格式化字符串
String world = String.format("hello, %s", "world");
System.out.println(world);
// 使用stream
List<String> strings = Arrays.asList("hello", "world", "yes");
String collect = strings.stream().collect(Collectors.joining(" "));
System.out.println(collect);
}
List集合分组partition
Java中浮点数比较
参考:
Java中浮点数的比较与运算
Java判空校验
字符串判空
方法一:最多人使用的一个方法,直观,方便,但效率很低,
if(s == null || s.equals(""))
方法二:比较字符串长度,效率高,s == null必须放在前面
if(s == null || s.length() == 0)
方法三:Java SE 6.0才开始提供的方法,效率和方法二几乎相等,但出于兼容性考虑,推荐使用方法二,
if(s == null || s.isEmpty())
方法四:这是一种比较直观,简便的方法,而且效率也非常的高,与方法二、三的效率差不多,
if (s == null || s == "")
方法五:空字符串前置调用equals方法(避免s为null报错),null前置判断
if("".equals(s) || null == s)
方法六:使用org.apache.commons.lang.StringUtils工具类,判断不为null也不是空
StringUtils.isNotBlank(a);
* StringUtils.isNotBlank(null) = false
* StringUtils.isNotBlank("") = false
* StringUtils.isNotBlank(" ") = false
* StringUtils.isNotBlank("bob") = true
* StringUtils.isNotBlank(" bob ") = true
*
StringUtils.isNotEmpty(a);
* StringUtils.isNotEmpty(null) = false
* StringUtils.isNotEmpty("") = false
* StringUtils.isNotEmpty(" ") = true
* StringUtils.isNotEmpty("bob") = true
* StringUtils.isNotEmpty(" bob ") = true
List判空
通常情况下会连用list != null && list.size > 0 来判断,或者直接使用HuTool中CollUtil工具的isEmpty、org.apache.commons中CollectionUtils的isEmpty
if (list != null && list.size > 0)
if (CollUtil.isEmpty(list)) // list为null或者size为0都返回true
if (CollectionUtils.isEmpty(list)) // list为null或者size为0都返回true
对象判空
判断一个对象是否为Null,可以使用java.util中的Objects.nonNull(obj)、hutool中的ObjectUtil或者直接 null != obj
if (Objects.isNull(list))
if (Objects.nonNull(obj))
if (ObjectUtil.isEmpty(obj))
if (ObjectUtil.isNotEmpty(list))
if (null != obj)
if (null == obj)
Optional对象的使用
Java8中Optional的出现就是用来防止NullpointException的,常见的方法有:
.empty():创建一个空的Optional实例
.of(T t) : 创建一个Optional 实例,为null时报异常
.ofNullable(T t):若t 不为null,创建Optional 实例,否则创建空实例
isPresent() : 判断容器中是否有值
ifPresent(Consume lambda) :容器若不为空则执行括号中的Lambda表达式
orElse(T t) : 获取容器中的元素,若容器为空则返回括号中的默认值
orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回s 获取的值
orElseThrow() :如果为空,就抛出定义的异常,如果不为空返回当前对象
map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回Optional.empty()
flatMap(Function mapper):与map 类似,要求返回值必须是Optional
T get() :获取容器中的元素,若容器为空则抛出NoSuchElement异常
使用示例:
Java Optional 实用判空实用实战,优雅永不过时
// baseInfo.getBlind()为null则取值false
boolean blind = Optional.ofNullable(baseInfo.getBlind()).orElse(false)
// task为空则抛出异常
Optional.ofNullable(task).orElseThrow(() -> new ProcessException(ErrorCodeEnum,SYSTMERROR) )
// 如果task不为空,则执行lamda表达式
Map<String,String> map = new HashMap<>(8);
Optional.ofNullable(task).ifPresent(d -> map.put("taskId",d.getTaskDefinitionkey());
List初始化方式
Map初始化方式
复制(拷贝)数组
1.原始赋值方法
2.使用 copyOf() 方法
3.使用 CopyOfRange() 方法
4.使用 arraycopy() 方法
5.使用 clone() 方法
// 原始赋值方法
public static void method01(int[] arr, int[] ans) {
for (int i = 0; i < arr.length; i++) {
ans[i] = arr[i];
}
System.out.println("复制的ans数组为 " + Arrays.toString(ans));
}
Arrays.copyOf(dataType[] srcArray,int length);
/**
其中,srcArray 表示要进行复制的数组,length 表示复制后的新数组的长度。
使用这种方法复制数组时,默认从原数组的第一个元素(索引值为 0)开始复制,目标数组的长度将为 length。如果 length 大于 srcArray.length,则目标数组中采用默认值填充;如果 length 小于 srcArray.length,则复制到第 length 个元素(索引值为 length-1)即止。
*/
Arrays.copyOfRange(dataType[] srcArray,int startIndex,int endIndex);
/**
其中:
srcArray 表示原数组。
startIndex 表示开始复制的起始索引,目标数组中将包含起始索引对应的元素,另外,startIndex 必须在 0 到 srcArray.length 之间。
endIndex 表示终止索引,目标数组中将不包含终止索引对应的元素,endIndex 必须大于等于 startIndex,可以大于 srcArray.length,如果大于 srcArray.length,则目标数组中使用默认值填充。
*/
System.arraycopy(dataType[] srcArray,int srcIndex,int destArray,int destIndex,int length);
/**
arraycopy() 方法位于 java.lang.System 类中
其中,srcArray 表示原数组;srcIndex 表示原数组中的起始索引;destArray 表示目标数组;destIndex 表示目标数组中的起始索引;length 表示要复制的数组长度。
使用此方法复制数组时,length+srcIndex 必须小于等于 srcArray.length,同时 length+destIndex 必须小于等于 destArray.length。
注意:目标数组必须已经存在,且不会被重构,相当于替换目标数组中的部分元素。
*/
array_name.clone();
/**
clone() 方法也可以实现复制数组。该方法是类 Object 中的方法,可以创建一个有单独内存空间的对象。因为数组也是一个 Object 类,因此也可以使用数组对象的 clone() 方法来复制数组。
clone() 方法的返回值是 Object 类型,要使用强制类型转换为适当的类型。
---clone()为浅拷贝(浅拷贝只是复制了对象的引用地址,两个对象指向同一个内存地址,所以修改其中任意的值,另一个值都会随之变化。深拷贝是将对象及值复制过来,两个对象修改其中任意的值另一个值不会改变)
*/
测试用例:
package com.zhuang;
import java.util.Arrays;
public class ArrayCopy {
public static void main(String[] args) {
// TODO Auto-generated method stub
int[] arr = new int[] { 57, 81, 68, 75, 91 };
int[] ans = new int[arr.length];
method01(arr, ans);
method02(arr, ans);
method03(arr, ans);
method04(arr, ans);
method05(arr, ans);
}
public static void method01(int[] arr, int[] ans) {
for (int i = 0; i < arr.length; i++) {
ans[i] = arr[i];
}
System.out.println("原始复制方法复制的ans数组为 " + Arrays.toString(ans));
}
public static void method02(int[] arr, int[] ans) {
ans = Arrays.copyOf(arr, arr.length + 3);
System.out.println("copyOf()方法复制的ans数组为 " + Arrays.toString(ans));
}
public static void method03(int[] arr, int[] ans) {
ans = Arrays.copyOfRange(arr, 0, arr.length + 3);
System.out.println("copyOfRange()方法复制的ans数组为 " + Arrays.toString(ans));
}
public static void method04(int[] arr, int[] ans) {
System.arraycopy(arr, 0, ans, 0, 5);
System.out.println("arraycopy()方法复制的ans数组为 " + Arrays.toString(ans));
}
public static void method05(int[] arr, int[] ans) {
ans = arr.clone();
System.out.println("clone()方法复制的ans数组为 " + Arrays.toString(ans));
}
}
Java集合List按日期升序或降序四种方法
HashMap遍历方式
- for循环遍历
- 迭代器遍历
- lambda表达式遍历
- stream流遍历
@Test
public void test(){
HashMap<Integer, String> mp = new HashMap(){{
put(1, "mike");
put(2, "lucy");
}};
// for循环
for(Map.Entry<Integer, String> entry : mp.entrySet()) {
System.out.println(entry.getKey() + "-" + entry.getValue());
}
for(Integer key : mp.keySet()) {
System.out.println(key + "-" + mp.get(key));
}
// iterator
Iterator<Map.Entry<Integer, String>> iterator = mp.entrySet().iterator();
while(iterator.hasNext()){
Map.Entry<Integer, String> next = iterator.next();
System.out.println(next.getKey() + "-" + next.getValue());
}
// lambda
mp.forEach((k, v) -> {
System.out.println(k + "-" + v);
});
// stream
mp.entrySet().stream().forEach(e -> System.out.println(e.getKey() + "-" + e.getValue()));
}
深拷贝和浅拷贝
参考:
详解java中的深拷贝和浅拷贝(clone()方法的重写、使用序列化实现真正的深拷贝)