一、按行读取文件返回List<String>.

1、java的nio包下使用

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
List<String> list = Files.readAllLines(Paths.get(PATH), StandardCharsets.UTF_8);

2、commons-io下使用

List<String> stringList = FileUtils.readLines(new File(PATH), StandardCharsets.UTF_8);

3、自定义实现

    /*** Buffer读取文件*/public static List<String> readFile(){List<String> list=new ArrayList<>();try (BufferedReader reader = Files.newBufferedReader(Paths.get(PATH), StandardCharsets.UTF_8)) {String line;while ((line = reader.readLine()) != null) {list.add(line);}} catch (IOException e) {log.error("file read error", e);}return list;}

二、相同List数据叠加.

    /*** List数据叠加** @param baseData 原始结合* @param addedData 叠加集合* @return 叠加集合*/public static List<Long> add(List<Long> baseData,List<Long> addedData){if(CollectionUtils.isEmpty(baseData)){return Collections.emptyList();}if(CollectionUtils.isEmpty(addedData)){return baseData;}if(baseData.size()!=addedData.size()){new GlobalException("base data size not equal added data");}for(int i=0;i<baseData.size();i++){baseData.set(i,baseData.get(i)+addedData.get(i));}return baseData;}

三、Long型数据转换int型,注意溢出时候会抛出异常便于排查.

System.out.println(Math.toIntExact(Long.MAX_VALUE));

 四、List数组之间转换以及常用的集合工具.

 // 1、空集合,底层自定义一个EmptyList实现,接口空list返回,不像new ArrayList分配不必要的内存空间Collections.emptyList();// 2、单值List,底层定义SingletonList,size为1Collections.singletonList(new Object());// 3、线程安全的List,底层定义SynchronizedList,方法定义通过synchronized代码实现线程安全,定义了一个SynchronizedCollectionCollections.synchronizedList(new ArrayList<>());// 4、不可变List,不支持修改,定义一个UnmodifiableCollection,UnmodifiableListCollections.unmodifiableList(new ArrayList<>());// 5、CopiesListList<String> stringList = Collections.nCopies(10, "dfs");
// int[]转换List<Integer>
List<Integer> list = Arrays.stream(num).boxed().collect(Collectors.toList());
System.out.println(list);
// list<Integer>转换Integer[]
Integer[] integers = list.stream().toArray(Integer[]::new);
System.out.println(Arrays.toString(integers));
// list<Integer>转换int[]
int[] result = list.stream().mapToInt(Integer::intValue).toArray();
System.out.println(Arrays.toString(result));
// List<Integer>转换Integer[]
Integer[] array = list.toArray(new Integer[0]);
System.out.println(Arrays.toString(array));
// Integer[]转换List<Integer>
List<Integer> asList = Arrays.asList(array);
System.out.println(asList);
// int[]->Integer[]
Integer[] integerNum = Arrays.stream(num).boxed().toArray(Integer[]::new);
// Integer[]->int[]
int[] intNum = Arrays.stream(integerNum).mapToInt(Integer::intValue).toArray();
    /*** Object转换Int** @param value* @return int*/private static int toInt(Object value){if(value instanceof BigDecimal){return ((BigDecimal)value).intValue();}if(value instanceof BigInteger){return ((BigInteger)value).intValue();}if(value instanceof Integer){return ((Integer) value).intValue();}if(value instanceof Long){return ((Long)value).intValue();}throw new GlobalException("to int error");}

数组排序,一般使用util包下的以及转换为集合或者是Apache下的包

五、SpringBoot获取初始化ApplicationContext.

    public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(SkywalkApplication.class, args);// 初始化ApplicationContextApplicationContextUtil.setApplicationContext(context);}

 ApplicationContextUtil工具类.

package com.boot.skywalk.bean;import com.boot.skywalk.exception.GlobalException;
import org.springframework.context.ApplicationContext;import java.util.Objects;/*** ApplicationContext工具类*/
public final class ApplicationContextUtil {/*** 获取ApplicationContext*/private static ApplicationContext applicationContext;private ApplicationContextUtil(){throw new GlobalException("unsupport create instance!");}public ApplicationContext getApplicationContext() {return applicationContext;}public static void setApplicationContext(ApplicationContext context) {applicationContext = context;}/*** 获取ApplicationContext** @return ApplicationContext*/public static ApplicationContext getInstance(){if(Objects.isNull(applicationContext)){new GlobalException("Spring FrameWork Init Failure");}return applicationContext;}
}

六、BeanUtil工具类封装.

package com.boot.skywalk.bean;import com.boot.skywalk.exception.GlobalException;
import org.apache.commons.collections.MapUtils;
import org.springframework.context.ApplicationContext;import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/*** Bean工具获取类*/
public final class CommonBeanUtils {private CommonBeanUtils(){throw new GlobalException("unsupport create instance");}/*** 获取ApplicationContext*/private static final ApplicationContext context=ApplicationContextUtil.getInstance();/*** 获取指定类型的Bean** @param clazz* @param <T>* @return*/public static  <T> T getBean(Class<T> clazz){return context.getBean(clazz);}/*** 获取指定名称的Bean** @param name* @return*/public static Object getBean(String name) {return context.getBean(name);}/*** 获取指定类型Bean列表** @param clazz clazz* @param <T>* @return List<T>*/public static  <T> List<T> getBeanList(Class<T> clazz){Map<String, T> beans = context.getBeansOfType(clazz);if(MapUtils.isEmpty(beans)){return Collections.emptyList();}List<T> list = beans.values().stream().collect(Collectors.toList());return list;}
}

七、Bean的属性复制时候推荐使用Spring框架下的.

①、Spring框架下的BeanUtil

②、Apache下的,有加锁获取逻辑,相对耗时方便推荐Spring框架的.

 八、工具类尽可能封装为单例模式,如RestClient、BeanUtils等.

九、当Maven多模块循环依赖时候,经过过滤器需要调用某个类的业务方法时候,这个时候可以使用反射调用.Spring的ReflectUtils或者是Class.forName();

Student student = (Student)ReflectUtils.newInstance(Student.class);
student.test();

十、全局异常定义.

public class GlobalException extends RuntimeException {public GlobalException() {super();}public GlobalException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {super(message, cause, enableSuppression, writableStackTrace);}/*** @param message* @param cause*/public GlobalException(String message, Throwable cause) {super(message, cause);}/*** @param message*/public GlobalException(String message) {super(message);}/*** @param cause*/public GlobalException(Throwable cause) {super(cause);}
}

可以根据一些项目自定义一些抽象异常子类,参考Spring框架的.

参数校验使用一些断言更佳.

Assert.isNull(str,"str message");

获取异常堆栈信息.

    public static List<Object> getStackInfoList(){List<Object> list = new ArrayList<>();try {int num=1/0;} catch (Exception e) {list.add(e.getStackTrace()[0].getClassName());list.add(e.getStackTrace()[0].getFileName());list.add(e.getStackTrace()[0].getClass());list.add(e.getStackTrace()[0].getLineNumber());}return list;}

 将异常信息拼接为字符串.

    /*** parse error to string** @param e* @return*/public static String toString(Throwable e) {StringWriter stringWriter = new StringWriter();e.printStackTrace(new PrintWriter(stringWriter));String errorMsg = stringWriter.toString();return errorMsg;}

普通执行器

    /*** 普通执行器** @param supplier* @param <T>* @return*/public static <T> T executor(Supplier<T> supplier){return supplier.get();}

适用一些幂等的Client调用.

   import com.boot.skywalk.exception.GlobalException;import lombok.extern.slf4j.Slf4j;import org.springframework.util.Assert;import java.util.function.Supplier;/*** 带重试次数执行器** @param supplier* @param retry* @param <T>* @return*/public static <T> T executorWithRetry(Supplier<T> supplier,int retry){Assert.isTrue(retry>=0, "retry times less than 0");int times=0;while(times++<retry){try {supplier.get();} catch (Exception e) {log.error("service method retry", e);}}log.error("service method already retry times={}",retry);throw new GlobalException("service method failed");}

十一、静态块+Map实现一些重构.

     1、如一些策略模式缓存策略实现类,StrategyFactory.

 private static final Map<String,IStrategy> STRATEGY=new HashMap<>();

十二、函数式接口的封装使用.

     1、回调接口.

/*** 通用回调函数式接口*/
@FunctionalInterface
public interface ICallback<T>{/*** 回调方法* @param t*/void callback(T t);
}

2、参数校验接口.

@FunctionalInterface
public interface ICheck<T> {/*** 通用业务校验* @param t*/void check(T t);
}

十三、List指定大小切割.

是直接在原来的List的改变的,partition,guava的也是一样的,一般使用批次更新查询和批次拉取数据,提升性能.

封装一个不改变原来List的partitionList.

    /*** 切割List,类似Lists.partition的切割** @param list* @param size* @param <T>* @return*/private static <T> List<List<T>> partition(List<T> list, int size){if(CollectionUtils.isEmpty(list)){throw new GlobalException("partition list is null");}if(size<0){throw new GlobalException("partition size less than 0");}int length=list.size();// 计算分组大小int partitionSize=(length+size-1)/size;List<List<T>> newList = new ArrayList<>(partitionSize);for(int i=0;i<partitionSize;i++){int fromIndex=i*size;int toIndex=Math.min((i+1)*size,length);newList.add(list.subList(fromIndex, toIndex));}return newList;}

使用方式如下:

        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, -6, 7, 8, 9, 10, -11, 12, 13, -14, 15, 16);// 分组List<List<Integer>> partitionList = partition(list, 5);System.out.println(partitionList);List<List<Integer>> result=new ArrayList<>();// 分组后再过滤partitionList.stream().forEach(partition->{List<Integer> collect = partition.stream().filter(num -> num > 0).collect(Collectors.toList());result.add(collect);});System.out.println(result);// 过滤再分组List<Integer> filterList = list.stream().filter(num -> num > 0).collect(Collectors.toList());List<List<Integer>> partitionResultList = partition(filterList, 5);System.out.println(partitionResultList);

不同的判定逻辑,注意业务代码中的使用. 

十三、时间工具类,参考Flink工具类封装.

org.apache.flink.api.common.time
public final class Time implements Serializable {private static final long serialVersionUID = -350254188460915999L;/** The time unit for this policy's time interval. */private final TimeUnit unit;/** The size of the windows generated by this policy. */private final long size;/** Instantiation only via factory method. */private Time(long size, TimeUnit unit) {this.unit = checkNotNull(unit, "time unit may not be null");this.size = size;}// ------------------------------------------------------------------------//  Properties// ------------------------------------------------------------------------/*** Gets the time unit for this policy's time interval.** @return The time unit for this policy's time interval.*/public TimeUnit getUnit() {return unit;}/*** Gets the length of this policy's time interval.** @return The length of this policy's time interval.*/public long getSize() {return size;}/*** Converts the time interval to milliseconds.** @return The time interval in milliseconds.*/public long toMilliseconds() {return unit.toMillis(size);}@Overridepublic String toString() {return toMilliseconds() + " ms";}@Overridepublic boolean equals(Object o) {if (this == o) {return true;}if (o == null || getClass() != o.getClass()) {return false;}Time time = (Time) o;return toMilliseconds() == time.toMilliseconds();}@Overridepublic int hashCode() {return Objects.hash(toMilliseconds());}// ------------------------------------------------------------------------//  Factory// ------------------------------------------------------------------------/*** Creates a new {@link Time} of the given duration and {@link TimeUnit}.** @param size The duration of time.* @param unit The unit of time of the duration, for example {@code TimeUnit.SECONDS}.* @return The time policy.*/public static Time of(long size, TimeUnit unit) {return new Time(size, unit);}/** Creates a new {@link Time} that represents the given number of milliseconds. */public static Time milliseconds(long milliseconds) {return of(milliseconds, TimeUnit.MILLISECONDS);}/** Creates a new {@link Time} that represents the given number of seconds. */public static Time seconds(long seconds) {return of(seconds, TimeUnit.SECONDS);}/** Creates a new {@link Time} that represents the given number of minutes. */public static Time minutes(long minutes) {return of(minutes, TimeUnit.MINUTES);}/** Creates a new {@link Time} that represents the given number of hours. */public static Time hours(long hours) {return of(hours, TimeUnit.HOURS);}/** Creates a new {@link Time} that represents the given number of days. */public static Time days(long days) {return of(days, TimeUnit.DAYS);}/*** Creates a new {@link Time} that represents the number of milliseconds in the given duration.*/public static Time fromDuration(Duration duration) {return milliseconds(duration.toMillis());}
}

十四、线程休眠工具类,封装逻辑.

线程休眠方式.

// 原生线程休眠
try {Thread.sleep(1000);
} catch (InterruptedException e) {e.printStackTrace();
}

并发工具包休眠方式

try {TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {e.printStackTrace();
}
import com.boot.skywalk.exception.GlobalException;
import lombok.extern.slf4j.Slf4j;import java.util.Objects;
import java.util.concurrent.TimeUnit;/*** 线程工具类封装,ThreadUtil*/
@Slf4j
public final class ThreadUtil {/*** Number of milliseconds in a standard second.*/public static final long MILLIS_PER_SECOND = 1000;/*** Number of milliseconds in a standard minute.*/public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND;/*** Number of milliseconds in a standard hour.*/public static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE;/*** Number of milliseconds in a standard day.*/public static final long MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR;/*** 校验时间单位** @param duration duration* @param unit unit*/public static void checkDurationLength(long duration, TimeUnit unit){long durationSeconds = TimeUnit.MILLISECONDS.convert(duration, unit);if(durationSeconds<0||durationSeconds>MILLIS_PER_DAY){log.error("illegal duration time,duration={},unit={}",duration,unit);throw new GlobalException("duration time is illegal");}}/*** 毫秒级中断线程** @param millSeconds*/public static void pauseThreadMillSeconds(long millSeconds){pauseThread(millSeconds, TimeUnit.MILLISECONDS);}/*** 秒级中断线程** @param seconds*/public static void pauseThreadSeconds(long seconds){pauseThread(seconds, TimeUnit.SECONDS);}/*** 中断线程** @param duration duration* @param unit unit*/public static void pauseThread(long duration,TimeUnit unit){if(Objects.isNull(unit)){log.error("TimeUnit is null");throw new GlobalException("TimeUnit is null");}checkDurationLength(duration, unit);try {unit.sleep(duration);} catch (InterruptedException e) {log.error("pause thread fail,duration={},unit={}",duration,unit,e);}}// 使用public static void main(String[] args) {System.out.println("start");pauseThreadSeconds(10);System.out.println("end");}
}

Spring框架反射工具类使用:

 一般在Maven多模块调用解决循环依赖的时候可以通过反射调用即可.

package com.boot.skywalk.util;import lombok.extern.slf4j.Slf4j;
import org.springframework.util.ReflectionUtils;import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;/*** ReflectTest.*/
@Slf4j
public class ReflectTest {/*** Reflect CLASS*/private static final String MAP_CLASS="com.boot.skywalk.util.MapUtil";public static void main(String[] args) {Class<?> forName=null;try {forName=Class.forName(MAP_CLASS);} catch (ClassNotFoundException e) {log.error("reflect class error!", e);}Map<String,String> map=new HashMap<>();map.put("Single","Single-Value");// 反射调用Method method = ReflectionUtils.findMethod(forName, "getMap", Map.class);Map<String,String> resp=null;try {resp=(Map<String,String>)method.invoke(null, map);} catch (IllegalAccessException e) {log.error("IllegalAccessException",e);} catch (InvocationTargetException e) {log.error("InvocationTargetException",e);}System.out.println(resp);}
}

 源码介绍:

 public static Method findMethod(Class<?> clazz, String name, @Nullable Class<?>... paramTypes) {Assert.notNull(clazz, "Class must not be null");Assert.notNull(name, "Method name must not be null");Class<?> searchType = clazz;while (searchType != null) {Method[] methods = (searchType.isInterface() ? searchType.getMethods() :getDeclaredMethods(searchType, false));for (Method method : methods) {if (name.equals(method.getName()) && (paramTypes == null || hasSameParams(method, paramTypes))) {return method;}}searchType = searchType.getSuperclass();}return null;}

MyBatisPlus的反射工具类:

ReflectionKit工具类介绍:

package com.baomidou.mybatisplus.core.toolkit;import org.apache.ibatis.logging.Log;
import org.apache.ibatis.logging.LogFactory;import java.lang.reflect.*;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.Stream;import static java.util.function.Function.identity;
import static java.util.stream.Collectors.toCollection;
import static java.util.stream.Collectors.toMap;/*** <p>* 反射工具类* </p>** @author Caratacus* @since 2016-09-22*/
public class ReflectionKit {private static final Log logger = LogFactory.getLog(ReflectionKit.class);/*** class field cache*/private static final Map<Class<?>, List<Field>> CLASS_FIELD_CACHE = new ConcurrentHashMap<>();private static final Map<Class<?>, Class<?>> PRIMITIVE_WRAPPER_TYPE_MAP = new IdentityHashMap<>(8);static {PRIMITIVE_WRAPPER_TYPE_MAP.put(Boolean.class, boolean.class);PRIMITIVE_WRAPPER_TYPE_MAP.put(Byte.class, byte.class);PRIMITIVE_WRAPPER_TYPE_MAP.put(Character.class, char.class);PRIMITIVE_WRAPPER_TYPE_MAP.put(Double.class, double.class);PRIMITIVE_WRAPPER_TYPE_MAP.put(Float.class, float.class);PRIMITIVE_WRAPPER_TYPE_MAP.put(Integer.class, int.class);PRIMITIVE_WRAPPER_TYPE_MAP.put(Long.class, long.class);PRIMITIVE_WRAPPER_TYPE_MAP.put(Short.class, short.class);}/*** <p>* 反射 method 方法名,例如 getId* </p>** @param field* @param str   属性字符串内容*/public static String getMethodCapitalize(Field field, final String str) {Class<?> fieldType = field.getType();// fix #176return StringUtils.concatCapitalize(boolean.class.equals(fieldType) ? "is" : "get", str);}/*** <p>* 反射 method 方法名,例如 setVersion* </p>** @param field Field* @param str   String JavaBean类的version属性名* @return version属性的setter方法名称,e.g. setVersion* @deprecated 3.0.8*/@Deprecatedpublic static String setMethodCapitalize(Field field, final String str) {return StringUtils.concatCapitalize("set", str);}/*** <p>* 获取 public get方法的值* </p>** @param cls    ignore* @param entity 实体* @param str    属性字符串内容* @return Object*/public static Object getMethodValue(Class<?> cls, Object entity, String str) {Map<String, Field> fieldMaps = getFieldMap(cls);try {Assert.notEmpty(fieldMaps, "Error: NoSuchField in %s for %s.  Cause:", cls.getSimpleName(), str);Method method = cls.getMethod(getMethodCapitalize(fieldMaps.get(str), str));return method.invoke(entity);} catch (NoSuchMethodException e) {throw ExceptionUtils.mpe("Error: NoSuchMethod in %s.  Cause:", e, cls.getSimpleName());} catch (IllegalAccessException e) {throw ExceptionUtils.mpe("Error: Cannot execute a private method. in %s.  Cause:", e, cls.getSimpleName());} catch (InvocationTargetException e) {throw ExceptionUtils.mpe("Error: InvocationTargetException on getMethodValue.  Cause:" + e);}}/*** <p>* 获取 public get方法的值* </p>** @param entity 实体* @param str    属性字符串内容* @return Object*/public static Object getMethodValue(Object entity, String str) {if (null == entity) {return null;}return getMethodValue(entity.getClass(), entity, str);}/*** <p>* 反射对象获取泛型* </p>** @param clazz 对象* @param index 泛型所在位置* @return Class*/public static Class<?> getSuperClassGenericType(final Class<?> clazz, final int index) {Type genType = clazz.getGenericSuperclass();if (!(genType instanceof ParameterizedType)) {logger.warn(String.format("Warn: %s's superclass not ParameterizedType", clazz.getSimpleName()));return Object.class;}Type[] params = ((ParameterizedType) genType).getActualTypeArguments();if (index >= params.length || index < 0) {logger.warn(String.format("Warn: Index: %s, Size of %s's Parameterized Type: %s .", index,clazz.getSimpleName(), params.length));return Object.class;}if (!(params[index] instanceof Class)) {logger.warn(String.format("Warn: %s not set the actual class on superclass generic parameter",clazz.getSimpleName()));return Object.class;}return (Class<?>) params[index];}/*** <p>* 获取该类的所有属性列表* </p>** @param clazz 反射类*/public static Map<String, Field> getFieldMap(Class<?> clazz) {List<Field> fieldList = getFieldList(clazz);return CollectionUtils.isNotEmpty(fieldList) ? fieldList.stream().collect(Collectors.toMap(Field::getName, field -> field)) : Collections.emptyMap();}/*** <p>* 获取该类的所有属性列表* </p>** @param clazz 反射类*/public static List<Field> getFieldList(Class<?> clazz) {if (Objects.isNull(clazz)) {return Collections.emptyList();}List<Field> fields = CLASS_FIELD_CACHE.get(clazz);if (CollectionUtils.isEmpty(fields)) {synchronized (CLASS_FIELD_CACHE) {fields = doGetFieldList(clazz);CLASS_FIELD_CACHE.put(clazz, fields);}}return fields;}/*** <p>* 获取该类的所有属性列表* </p>** @param clazz 反射类*/public static List<Field> doGetFieldList(Class<?> clazz) {if (clazz.getSuperclass() != null) {/* 排除重载属性 */Map<String, Field> fieldMap = excludeOverrideSuperField(clazz.getDeclaredFields(),/* 处理父类字段 */getFieldList(clazz.getSuperclass()));List<Field> fieldList = new ArrayList<>();/** 重写父类属性过滤后处理忽略部分,支持过滤父类属性功能* 场景:中间表不需要记录创建时间,忽略父类 createTime 公共属性* 中间表实体重写父类属性 ` private transient Date createTime; `*/fieldMap.forEach((k, v) -> {/* 过滤静态属性 */if (!Modifier.isStatic(v.getModifiers())/* 过滤 transient关键字修饰的属性 */&& !Modifier.isTransient(v.getModifiers())) {fieldList.add(v);}});return fieldList;} else {return Collections.emptyList();}}/*** <p>* 排序重置父类属性* </p>** @param fields         子类属性* @param superFieldList 父类属性*/public static Map<String, Field> excludeOverrideSuperField(Field[] fields, List<Field> superFieldList) {// 子类属性Map<String, Field> fieldMap = Stream.of(fields).collect(toMap(Field::getName, identity()));superFieldList.stream().filter(field -> !fieldMap.containsKey(field.getName())).forEach(f -> fieldMap.put(f.getName(), f));return fieldMap;}/*** 获取字段get方法** @param cls   class* @param field 字段* @return Get方法*/public static Method getMethod(Class<?> cls, Field field) {try {return cls.getDeclaredMethod(ReflectionKit.getMethodCapitalize(field, field.getName()));} catch (NoSuchMethodException e) {throw ExceptionUtils.mpe("Error: NoSuchMethod in %s.  Cause:", e, cls.getName());}}/*** 判断是否为基本类型或基本包装类型** @param clazz class* @return 是否基本类型或基本包装类型*/public static boolean isPrimitiveOrWrapper(Class<?> clazz) {Assert.notNull(clazz, "Class must not be null");return (clazz.isPrimitive() || PRIMITIVE_WRAPPER_TYPE_MAP.containsKey(clazz));}
}
List<Field> fieldList = ReflectionKit.getFieldList(ReflectTest.class);
System.out.println(fieldList);

异常堆栈信息打印:

package com.boot.skywalk.vo;import java.util.LinkedHashMap;
import java.util.Map;public class ExceptionUtil {public static void main(String[] args) {try{int num=1/0;}catch (ArithmeticException e){System.out.println(recordExceptionMap(e));}}/*** 记录Exception堆栈信息** @param exception* @return Map<String,Object>*/public static Map<String,Object> recordExceptionMap(Exception exception){Map<String,Object> map=new LinkedHashMap<>();StackTraceElement stackTraceElement = exception.getStackTrace()[0];map.put("class_name",stackTraceElement.getClassName());map.put("file_name",stackTraceElement.getFileName());map.put("method_name",stackTraceElement.getMethodName());map.put("line_number",stackTraceElement.getLineNumber());return map;}
}

Stream的静态方法,流的特点:无法重复消费、不存放数据、不改变数据源,具有延迟性,只有终端执行操作了,中间才会执行.

        // Stream的静态方法Stream<Integer> stream0 = Stream.of(7, 8, 9, 10, 11);Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5, 6);// 合并流Stream<Integer> concatStream = Stream.concat(stream0, stream1);concatStream.forEach(System.out::println);// 迭代无限流Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);stream2.forEach(System.out::println);// 生产无限流Stream<Double> stream3 = Stream.generate(Math::random).limit(3);stream3.forEach(System.out::println);

Java8 Stream:2万字20个实例,玩转集合的筛选、归约、分组、聚合

分区和分组区别:主要是看函数式接口,Function和Predicate

    public static <T>Collector<T, ?, Map<Boolean, List<T>>> partitioningBy(Predicate<? super T> predicate) {return partitioningBy(predicate, toList());}
    public static <T, K, A, D>Collector<T, ?, Map<K, D>> groupingBy(Function<? super T, ? extends K> classifier,Collector<? super T, A, D> downstream) {return groupingBy(classifier, HashMap::new, downstream);}

常用总结:

toMap-->stream转为map
Function.identity()-->返回stream中的元素
集合-->Stream:stream()
数组-->Stream:Stream.of(T t)或者Arrays.stream(T[] t)
任意元素-->Stream:Stream.of(T... values)
归约:是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。

获取字符串最大长度

    public static void getMaxStr(){List<String> list = Arrays.asList("abb", "abcd", "fegc", "efe", "adfes");// 最长字符串长度int maxLength = list.stream().filter(s -> s.startsWith("a")).mapToInt(r -> r.length()).max().orElse(0);System.out.println(maxLength);// 最长字符串Optional<String> optional = list.stream().filter(s -> s.startsWith("a")).max(Comparator.comparing(String::length));String string = Optional.ofNullable(optional.get()).orElse("");System.out.println(string);}

对象属性求和

    /*** Stream计算属性和* @return int*/public static int getSum(){Student s1 = new Student("张一",5);Student s2 = new Student("张二",3);Student s3 = new Student("张三",4);Student s4 = new Student("张四",1);List<Student> list=new ArrayList<>();list.add(s1);list.add(s2);list.add(s3);list.add(s4);// 计算属性和:返回一个IntStream其中包含给定函数应用于此流得元素的结果int sum = list.stream().mapToInt(o -> Objects.isNull(o.getAge()) ? 0 : o.getAge()).sum();List<Integer> ageList = list.stream().map(o -> Objects.isNull(o.getAge()) ? 0 : o.getAge()).collect(Collectors.toList());// reduce规约计算Optional<Integer> result = ageList.stream().reduce(Integer::sum);System.out.println(result.get());return sum;}

BIO流读取:

①、字节流读取

    /*** 通过字节流实现文件复制:FileInputStream/FileOutputStream*/public static void writeByInputStream(){//使用 jdk7 引入的自动关闭资源的 try 语句(该资源类要实现 AutoCloseable 或 Closeable 接口)try (FileInputStream fis = new FileInputStream("D:\\红色电视剧.txt");FileOutputStream fos = new FileOutputStream("D:\\红色电视剧_copy.txt")) {byte[] buf = new byte[126];int hasRead = 0;while ((hasRead = fis.read(buf)) > 0) {//每次读取多少就写多少fos.write(buf, 0, hasRead);}} catch (Exception e) {log.error("write error", e);}}

②、字符流读取

    /*** 通过字符流读取:FileReader/FileWriter*/public static void writeByReader(){//使用 jdk7 引入的自动关闭资源的 try 语句try (FileReader fr = new FileReader("D:\\红色电视剧.txt");FileWriter fw = new FileWriter("D:\\红色电视剧_copy1.txt")) {char[] buf = new char[126];int hasRead = 0;while ((hasRead = fr.read(buf)) > 0) {//每次读取多少就写多少fw.write(buf, 0, hasRead);}} catch (Exception e){log.error("write error", e);}}

③、字符缓存流,按照行读取

    /*** 通过字符缓存流读取:BufferedReader/BufferedWriter*/public static void writeByBufferReader(){//使用普通的 Reader 不方便整行读取,可以使用 BufferReader 包装,资源变量要定义在 try()中,否则不会自动关闭try (FileReader fr = new FileReader("D:\\红色电视剧.txt");FileWriter fw = new FileWriter("D:\\红色电视剧_copy2.txt");// 装饰缓存流BufferedReader bufferedReader = new BufferedReader(fr);BufferedWriter bufferedWriter = new BufferedWriter(fw)) {String line;while ((line = bufferedReader.readLine()) != null) {//每次读取一行、写入一行bufferedWriter.write(line);bufferedWriter.newLine();}} catch (Exception e) {log.error("write error", e);}}

Bean和Map的工具类封装,基于cglib包实现.

        <dependency><groupId>cglib</groupId><artifactId>cglib-nodep</artifactId><version>3.3.0</version></dependency>

Mybatis-Plus框架封装BeanUtils工具类

package com.baomidou.mybatisplus.core.toolkit;import static java.util.stream.Collectors.toList;import java.util.Collections;
import java.util.List;
import java.util.Map;import net.sf.cglib.beans.BeanMap;/*** Bean 转换工具类* <p>使用请依赖 cglib 包</p>** @author hubin HCL* @since 2018-06-12*/
public final class BeanUtils {private BeanUtils() {}/*** 将对象装换为 map,对象转成 map,key肯定是字符串** @param bean 转换对象* @return 返回转换后的 map 对象*/@SuppressWarnings("unchecked")public static Map<String, Object> beanToMap(Object bean) {return null == bean ? null : BeanMap.create(bean);}/*** map 装换为 java bean 对象** @param map   转换 MAP* @param clazz 对象 Class* @return 返回 bean 对象*/public static <T> T mapToBean(Map<String, Object> map, Class<T> clazz) {T bean = ClassUtils.newInstance(clazz);BeanMap.create(bean).putAll(map);return bean;}/*** List&lt;T&gt; 转换为 List&lt;Map&lt;String, Object&gt;&gt;** @param beans 转换对象集合* @return 返回转换后的 bean 列表*/public static <T> List<Map<String, Object>> beansToMaps(List<T> beans) {if (CollectionUtils.isEmpty(beans)) {return Collections.emptyList();}return beans.stream().map(BeanUtils::beanToMap).collect(toList());}/*** List&lt;Map&lt;String, Object&gt;&gt; 转换为 List&lt;T&gt;** @param maps  转换 MAP 集合* @param clazz 对象 Class* @return 返回转换后的 bean 集合*/public static <T> List<T> mapsToBeans(List<Map<String, Object>> maps, Class<T> clazz) {if (CollectionUtils.isEmpty(maps)) {return Collections.emptyList();}return maps.stream().map(e -> mapToBean(e, clazz)).collect(toList());}
}

测试一下工具:

    /*** 测试Bean转换Map* @return Map<String, Object>*/public static Map<String, Object> beanToMapTest(){Student s1 = new Student("张一",5);Map<String, Object> map = beanToMap(s1);return map;}/*** 测试List<Bean>转换List<Map>* @return Map<String, Object>*/public static List<Map<String, Object>> beanListToMapTest(){Student s1 = new Student("张一",5);Student s2 = new Student("张二",4);Student s3 = new Student("张三",3);Student s4 = new Student("张四",2);Student s5 = new Student(null,1);List<Student> list=new ArrayList<>();list.add(s1);list.add(s2);list.add(s3);list.add(s4);list.add(s5);List<Map<String, Object>> maps = beansToMaps(list);return maps;}
    public static void main(String[] args) {Map<String, Object> map = beanToMapTest();System.out.println("Bean转换Map:"+map);Student student = mapToBean(map, Student.class);System.out.println("Map转换Bean"+student);List<Map<String, Object>> list = beanListToMapTest();System.out.println("ListBean转换ListMap"+list);List<Student> studentList = mapsToBeans(list, Student.class);System.out.println("ListMap转换ListBean"+studentList);}

十五、并发测试工具类

1、开源的HuTool测试工具类.

        <dependency><groupId>cn.hutool</groupId><artifactId>hutool-core</artifactId><version>5.8.6</version></dependency>
package com.boot.skywalk;import cn.hutool.core.thread.ConcurrencyTester;
import cn.hutool.core.thread.ThreadUtil;
import lombok.extern.slf4j.Slf4j;import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
import java.util.stream.IntStream;/*** Hutool并发工具类测试*/
@Slf4j
public class ConcurrentTest {private static final Map<String, List<Integer>> MAP = new HashMap<>();private static final Map<String, List<Integer>> CONCURRENTHASH_MAP = new ConcurrentHashMap<>();public static void main(String[] args) throws IOException {// 1、定义多少个线程,这里是100个并发,每个执行业务逻辑是循环计算ConcurrencyTester concurrencyTester = ThreadUtil.concurrencyTest(100, new Runnable() {@Overridepublic void run() {List<Integer> list = IntStream.range(1, 1001).boxed().collect(Collectors.toList());for(int i=0;i<100;i++){MAP.put(Thread.currentThread().getName()+"-"+i, list);CONCURRENTHASH_MAP.put(Thread.currentThread().getName()+"-"+i, list);}}});//MAP.forEach((key, value) -> {//    log.info("key={},value={}", key, value);//});log.info("total HashMap size={},ConcurrentHashMap size={}",MAP.size(),CONCURRENTHASH_MAP.size());log.info("total cost time={}", concurrencyTester.getInterval()+"ms");// 2、关闭concurrencyTester.close();}
}

同时验证HashMap是线程不安全的.

源码也是比较简单的,ExecutorService+CountDownLatch

package cn.hutool.core.thread;import cn.hutool.core.exceptions.UtilException;import java.io.Closeable;
import java.io.IOException;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;/*** 线程同步结束器<br>* 在完成一组正在其他线程中执行的操作之前,它允许一个或多个线程一直等待。** <pre>* ps:* //模拟1000个线程并发* SyncFinisher sf = new SyncFinisher(1000);* sf.addWorker(() -&gt; {*      // 需要并发测试的业务代码* });* sf.start()* </pre>*** @author Looly* @since 4.1.15*/
public class SyncFinisher implements Closeable {private final Set<Worker> workers;private final int threadSize;private ExecutorService executorService;private boolean isBeginAtSameTime;/** 启动同步器,用于保证所有worker线程同时开始 */private final CountDownLatch beginLatch;/** 结束同步器,用于等待所有worker线程同时结束 */private CountDownLatch endLatch;/*** 构造** @param threadSize 线程数*/public SyncFinisher(int threadSize) {this.beginLatch = new CountDownLatch(1);this.threadSize = threadSize;this.workers = new LinkedHashSet<>();}/*** 设置是否所有worker线程同时开始** @param isBeginAtSameTime 是否所有worker线程同时开始* @return this*/public SyncFinisher setBeginAtSameTime(boolean isBeginAtSameTime) {this.isBeginAtSameTime = isBeginAtSameTime;return this;}/*** 增加定义的线程数同等数量的worker** @param runnable 工作线程* @return this*/public SyncFinisher addRepeatWorker(final Runnable runnable) {for (int i = 0; i < this.threadSize; i++) {addWorker(new Worker() {@Overridepublic void work() {runnable.run();}});}return this;}/*** 增加工作线程** @param runnable 工作线程* @return this*/public SyncFinisher addWorker(final Runnable runnable) {return addWorker(new Worker() {@Overridepublic void work() {runnable.run();}});}/*** 增加工作线程** @param worker 工作线程* @return this*/synchronized public SyncFinisher addWorker(Worker worker) {workers.add(worker);return this;}/*** 开始工作<br>* 执行此方法后如果不再重复使用此对象,需调用{@link #stop()}关闭回收资源。*/public void start() {start(true);}/*** 开始工作<br>* 执行此方法后如果不再重复使用此对象,需调用{@link #stop()}关闭回收资源。** @param sync 是否阻塞等待* @since 4.5.8*/public void start(boolean sync) {endLatch = new CountDownLatch(workers.size());if(null == this.executorService || this.executorService.isShutdown()){this.executorService = ThreadUtil.newExecutor(threadSize);}for (Worker worker : workers) {executorService.submit(worker);}// 保证所有worker同时开始this.beginLatch.countDown();if (sync) {try {this.endLatch.await();} catch (InterruptedException e) {throw new UtilException(e);}}}/*** 结束线程池。此方法执行两种情况:* <ol>*     <li>执行start(true)后,调用此方法结束线程池回收资源</li>*     <li>执行start(false)后,用户自行判断结束点执行此方法</li>* </ol>** @since 5.6.6*/public void stop(){if(null != this.executorService){this.executorService.shutdown();}this.executorService = null;clearWorker();}/*** 清空工作线程对象*/public void clearWorker() {workers.clear();}/*** 剩余任务数** @return 剩余任务数*/public long count() {return endLatch.getCount();}@Overridepublic void close() throws IOException {stop();}/*** 工作者,为一个线程** @author xiaoleilu**/public abstract class Worker implements Runnable {@Overridepublic void run() {if (isBeginAtSameTime) {try {beginLatch.await();} catch (InterruptedException e) {throw new UtilException(e);}}try {work();} finally {endLatch.countDown();}}/*** 任务内容*/public abstract void work();}
}

2、自定义

    public static void concurrencyTest(){concurrencyExecute(100, ()->{List<Integer> list = IntStream.range(1, 1001).boxed().collect(Collectors.toList());for(int i=0;i<100;i++){MAP.put(Thread.currentThread().getName()+"-"+i, list);CONCURRENTHASH_MAP.put(Thread.currentThread().getName()+"-"+i, list);}return null;});log.info("total HashMap size={},ConcurrentHashMap size={}",MAP.size(),CONCURRENTHASH_MAP.size());}public static <T> T concurrencyExecute(int threadNumber, Supplier<T> supplier) {CountDownLatch start = new CountDownLatch(1);CountDownLatch end = new CountDownLatch(threadNumber);ExecutorService executorService = Executors.newFixedThreadPool(threadNumber);T object = null;for (int i = 0; i < threadNumber; i++) {executorService.submit(() -> {try {// 1、先阻塞这别让这个线程跑起来start.await();// 具体的业务方法(本地方法 or 远程调用)supplier.get();} catch (InterruptedException e) {log.error("error message",e);Thread.currentThread().interrupt();} finally {// 一个线程跑完 end计数器-1end.countDown();}});}// start-1 所有线程启动,同时进行业务计算start.countDown();// 阻塞直到所有线程执行完毕try {end.await();} catch (InterruptedException e) {log.error("error message",e);Thread.currentThread().interrupt();}executorService.shutdown();return object;}

十六、MyBatis的防止SQL注入写法.

   1、in查询写法

   错误写法:不是用$替换

Select * from news where id in (#{ids})

正确写法:

    <!-- in查询写法--><select id="queryListByIds" resultType="com.boot.skywalk.entity.UserInfo">SELECT * from user_info where create_time>#{createTime} and id in<foreach collection="list" item="idItem" open="(" close=")" separator="," >#{idItem}</foreach></select>

2、like模糊查询写法

 错误写法:

Select * from news where title like ‘%#{title}%’

正确写法: 

    <!--左匹配和右匹配 -->
<!--    select * from user_info where user_name like concat('%',#{userName},'%')--><select id="queryListByUserName" resultType="com.boot.skywalk.entity.UserInfo">select * from user_info where user_name like concat(#{userName},'%')</select>

十七、时间格式转换

yyyy-MM-dd'T'HH:mm:ss.SSSXXX转换yyyy-MM-dd HH:mm:ss
yyyy-MM-dd'T'HH:mm:ss.SSSZ转换yyyy-MM-dd HH:mm:ss
    /*** 时间转换Z表示时区,RFC 822时区* @param date* @return*/private static String formateUtcRfc(Date date){String format="yyyy-MM-dd'T'HH:mm:ss.SSSZ";SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);String result = simpleDateFormat.format(date);System.out.println(result);return result;}/*** 时间转换Z表示时区,ISO 8601时区* @param date* @return*/private static String formateUtcIso(Date date){String format="yyyy-MM-dd'T'HH:mm:ss.SSSXXX";SimpleDateFormat simpleDateFormat = new SimpleDateFormat(format);String result = simpleDateFormat.format(date);System.out.println(result);return result;}/*** yyyy-MM-dd'T'HH:mm:ss.SSSZ转换yyyy-MM-dd HH:mm:ss* 2022-11-07T20:50:15.144+08:00转换2022-11-07 20:51:51* SSS表示毫秒* Z表示时区*/private static void toUtcRfcString(){SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZ");SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date=null;try {date = simpleDateFormat.parse(formateUtcRfc(new Date()));} catch (ParseException e) {e.printStackTrace();}System.out.println(simpleDateFormat1.format(date));}/*** yyyy-MM-dd'T'HH:mm:ss.SSSXXX转换yyyy-MM-dd HH:mm:ss* 2022-11-07T20:51:51.704+0800转换2022-11-07 20:51:51* SSS表示毫秒* XXX表示时区时间格式*/private static void toUtcIsoString(){SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX");SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");Date date=null;try {date = simpleDateFormat.parse(formateUtcIso(new Date()));} catch (ParseException e) {e.printStackTrace();}System.out.println(simpleDateFormat1.format(date));}

 private static final Map<ISO, String> ISO_PATTERNS;static {Map<ISO, String> formats = new EnumMap<>(ISO.class);formats.put(ISO.DATE, "yyyy-MM-dd");formats.put(ISO.TIME, "HH:mm:ss.SSSXXX");formats.put(ISO.DATE_TIME, "yyyy-MM-dd'T'HH:mm:ss.SSSXXX");ISO_PATTERNS = Collections.unmodifiableMap(formats);}
public enum DateField {/*** 世纪** @see Calendar#ERA*/ERA(Calendar.ERA),/*** 年** @see Calendar#YEAR*/YEAR(Calendar.YEAR),/*** 月** @see Calendar#MONTH*/MONTH(Calendar.MONTH),/*** 一年中第几周** @see Calendar#WEEK_OF_YEAR*/WEEK_OF_YEAR(Calendar.WEEK_OF_YEAR),/*** 一月中第几周** @see Calendar#WEEK_OF_MONTH*/WEEK_OF_MONTH(Calendar.WEEK_OF_MONTH),/*** 一月中的第几天** @see Calendar#DAY_OF_MONTH*/DAY_OF_MONTH(Calendar.DAY_OF_MONTH),/*** 一年中的第几天** @see Calendar#DAY_OF_YEAR*/DAY_OF_YEAR(Calendar.DAY_OF_YEAR),/*** 周几,1表示周日,2表示周一** @see Calendar#DAY_OF_WEEK*/DAY_OF_WEEK(Calendar.DAY_OF_WEEK),/*** 天所在的周是这个月的第几周** @see Calendar#DAY_OF_WEEK_IN_MONTH*/DAY_OF_WEEK_IN_MONTH(Calendar.DAY_OF_WEEK_IN_MONTH),/*** 上午或者下午** @see Calendar#AM_PM*/AM_PM(Calendar.AM_PM),/*** 小时,用于12小时制** @see Calendar#HOUR*/HOUR(Calendar.HOUR),/*** 小时,用于24小时制** @see Calendar#HOUR*/HOUR_OF_DAY(Calendar.HOUR_OF_DAY),/*** 分钟** @see Calendar#MINUTE*/MINUTE(Calendar.MINUTE),/*** 秒** @see Calendar#SECOND*/SECOND(Calendar.SECOND),/*** 毫秒** @see Calendar#MILLISECOND*/MILLISECOND(Calendar.MILLISECOND);// ---------------------------------------------------------------private final int value;DateField(int value) {this.value = value;}public int getValue() {return this.value;}/*** 将 {@link Calendar}相关值转换为DatePart枚举对象<br>** @param calendarPartIntValue Calendar中关于Week的int值* @return DateField*/public static DateField of(int calendarPartIntValue) {switch (calendarPartIntValue) {case Calendar.ERA:return ERA;case Calendar.YEAR:return YEAR;case Calendar.MONTH:return MONTH;case Calendar.WEEK_OF_YEAR:return WEEK_OF_YEAR;case Calendar.WEEK_OF_MONTH:return WEEK_OF_MONTH;case Calendar.DAY_OF_MONTH:return DAY_OF_MONTH;case Calendar.DAY_OF_YEAR:return DAY_OF_YEAR;case Calendar.DAY_OF_WEEK:return DAY_OF_WEEK;case Calendar.DAY_OF_WEEK_IN_MONTH:return DAY_OF_WEEK_IN_MONTH;case Calendar.AM_PM:return AM_PM;case Calendar.HOUR:return HOUR;case Calendar.HOUR_OF_DAY:return HOUR_OF_DAY;case Calendar.MINUTE:return MINUTE;case Calendar.SECOND:return SECOND;case Calendar.MILLISECOND:return MILLISECOND;default:return null;}}
}

十八、FastJson中Json数组转换List<T>

class Function{private String functionId;private Boolean needBuy;private String functionName;public Function(){}public Function(String functionId, Boolean needBuy, String functionName) {this.functionId = functionId;this.needBuy = needBuy;this.functionName = functionName;}public String getFunctionId() {return functionId;}public void setFunctionId(String functionId) {this.functionId = functionId;}public Boolean getNeedBuy() {return needBuy;}public void setNeedBuy(Boolean needBuy) {this.needBuy = needBuy;}public String getFunctionName() {return functionName;}public void setFunctionName(String functionName) {this.functionName = functionName;}@Overridepublic String toString() {return "Function{" +"functionId='" + functionId + '\'' +", needBuy=" + needBuy +", functionName='" + functionName + '\'' +'}';}
}
String jsonStr= "[{\"functionId\":\"14\",\"needBuy\":false,\"functionName\":\"功能1\"},{\"functionId\":\"17\",\"needBuy\":false,\"functionName\":\"功能2\"}]";
// JSONArray转换List<T>
List<Function> functions = JSON.parseArray(jsonStr, Function.class);
// JSONObject实现
List<Function> list = jsonArray.stream().map(item -> {Function function = JSONObject.parseObject(JSONObject.toJSONString(item), Function.class);return function;
}).collect(Collectors.toList());

Idea将字符串转化为JSON字符串的方式 :鼠标放在括号内,然后Alt+Enter即可看到编辑.

十九、时间月份增加或者减少

 主要使用java8的LocalDate.now().plusMonths

    /*** 默认是增加月份** @param num* @return*/private static List<String> getRangDateMonthList(int num){return getRangDateMonthList(num,true);}/*** 返回指定月份的集合* @param num 月份* @param status 状态,true为增加,false为减少* @return*/private static List<String> getRangDateMonthList(int num,boolean status){if(num<=0){return Collections.emptyList();}List<String> list=new ArrayList<>();for(int i=0;i<num;i++){long plus=i;if(!status){plus=Long.parseLong("-"+i);}list.add(LocalDate.now().plusMonths(plus).toString().substring(0,7));}return list;}

二十、函数式接口的封装使用

1、定义函数式接口

package com.boot.skywalk.task;
/*** 通用数据清理任务接口*/
@FunctionalInterface
public interface ICleanData {/*** 清理数据*/void cleanData();
}
package com.boot.skywalk.task;
/*** 通用检验* @param <T>*/
@FunctionalInterface
public interface ICheck<T> {/*** 通用检验* @param t*/void check(T t);
}

Dubbo中的检验,可以扩展为函数式接口

package org.apache.dubbo.common.status;import org.apache.dubbo.common.extension.ExtensionScope;
import org.apache.dubbo.common.extension.SPI;/*** StatusChecker*/
@SPI(scope = ExtensionScope.APPLICATION)
public interface StatusChecker {/*** check status** @return status*/Status check();}

  定时任务上传采集数据

import org.apache.dubbo.common.extension.SPI;@SPI
public interface Merger<T> {T merge(T... items);}

package org.apache.dubbo.rpc.cluster.merger;import org.apache.dubbo.common.utils.ArrayUtils;
import org.apache.dubbo.rpc.cluster.Merger;import java.util.Arrays;
import java.util.Objects;public class IntArrayMerger implements Merger<int[]> {@Overridepublic int[] merge(int[]... items) {if (ArrayUtils.isEmpty(items)) {return new int[0];}return Arrays.stream(items).filter(Objects::nonNull).flatMapToInt(Arrays::stream).toArray();}}

二十一、优化if/else/switch的方法,降低程序圈复杂度、提高扩展性.

     1、使用卫语句提前返回,包括各种配置项检查、断言检查、参数校验等.

     2、使用三目表达式.

     3、使用Optional来减少返回.

     4、使用静态块+Map的缓存.

     5、使用策略模式来减少不必要的分支.

     6、使用枚举结合方法来实现.

     7、开发完功能后,整理代码,包括格式化命名,圈复杂度和深度,以及IDAE重构快捷键抽取一下,提供复用,减少重复.

    8、多阅读开源框架代码,学习实践设计模式、编码技巧、软件设计思想对日常开发很有帮助.

JAVA开发常用API及封装相关推荐

  1. java中常用API、Scanner类、匿名对象、Random类、ArrayList类、对象数组

    java中常用API: API:Application Programming Interface,应用程序编程接口.Java API是JDK中提供给我们使用的类的说明文档.这些类将底层的代码实现封装 ...

  2. java开发常用jar包_java开发常用jar包

    mail.jar与activation.jar 里面包含了activation.jar和mail.jar两个包.通过里面的类的调用便可以达到发送电子邮件的目的 commons-beanutils.ja ...

  3. Java开发常用包、接口和类

    一.JDK中常用包 1.java.lang 这个是系统的基础类: 2.java.io 这里面是所有输入输出有关的类,比如文件操作等: 3.java.nio 为了完善 io 包中的功能,提高 io 包中 ...

  4. Java开发常用词汇表

    Java开发常用英语单词表 第一章: public['pʌblik] 公共的,公用的 static['stætik] 静的;静态的;静止的 void:[vɔid] 空的 main:[mein] 主要的 ...

  5. Java开发常用英语单词表

    Java开发常用英语单词表 第一章: public['pʌblik] 公共的,公用的 static['stætik] 静的;静态的;静止的 void:[vɔid] 空的 main:[mein] 主要的 ...

  6. uni-app H5兼容ios问题+微信扫一扫、微信支付等常用api代码封装

    最近公司需要用uni开发一个项目,项目中遇到的问题记录一下,方便下次不采坑 场景:         使用wx自带sdk完成,扫一扫.微信登录.微信支付 引用方式: // index.html引入 &l ...

  7. Java程序员从笨鸟到菜鸟之(五)java开发常用类(包装,数字处理集合等)(下)...

     本文来自:曹胜欢博客专栏.转载请注明出处:http://blog.csdn.net/csh624366188 写在前面:由于前天项目老师建设局的项目快到验收阶段,所以,前天晚上通宵,昨天睡了大半天, ...

  8. Java程序员从笨鸟到菜鸟之(五)java开发常用类(包装,数字处理集合等)(下)

    写在前面:由于前天项目老师建设局的项目快到验收阶段,所以,前天晚上通宵,昨天睡了大半天,下午我们宿舍聚会,所以时间有点耽误,希望大家见谅 上接: Java程序员从笨鸟到菜鸟之(四)java开发常用类( ...

  9. java 操作vss,java开发常用工具总结,java开发常用工具

    java开发常用工具总结,java开发常用工具 1.editplus editplus 是我使用最频繁的工具,不管是java程序还是其他的语言的程序,本人都使用它,方便好用,速度快.如果配置好的话,可 ...

最新文章

  1. Fiddler抓取https相关设置
  2. codeforces1437 E. Make It Increasing——最长上升子序列
  3. “睡服”面试官系列第十四篇之数组的扩展(建议收藏学习)
  4. 一个mapper接口有多个mapper.xml 文件_MyBatis 源码解析:映射文件的加载与解析(上)
  5. 两个平面的位置关系和判定方程组解_精品获奖教案 1.2.4平面与平面的位置关系(2)教案 苏教版必修2...
  6. SHA256 算法 加密文件、防文件篡改、文件校验
  7. 两张表之间进行数据库查询时的聚合函数用法
  8. 图书里的音频二维码如何实现呢?
  9. 微信开发工具使用git
  10. Java | Comparable接口和Comparator接口比较
  11. 大于4G的文件无法拷贝到U盘
  12. 利用RNAi研究马铃薯基因功能——StRIK与外表皮应激反应
  13. 使用Linux命令删除Android的一些垃圾文件
  14. 怎样提取网页视频中的音频文件
  15. win10/win11安装时提示:“我们无法创建新的分区,也找不到现有分区”的解决方法
  16. Python:max函数获取列表最大值
  17. vue created 无效
  18. Python爬取手机壁纸
  19. scala安装及环境配置
  20. HTML+css 会旋转的可乐瓶子

热门文章

  1. 使用opencv检测图片中的牙齿(附C++代码)
  2. 就是这么厉害!李开复新书《AI·未来》全球首发,不想被AI取代的你值得拥有...
  3. CloudCompare学习记录(二)教程
  4. 检讨书生成微信小程序工具源码-支持流量主
  5. 《太空一号》[2012最新吕克·贝松监制][BD-RMVB.720p.中英双字]
  6. 苏州大学研究生计算机考数二,上海大学,考研界第二个“苏州大学”
  7. 《那些年啊,那些事——一个程序员的奋斗史》——75
  8. jQuery仿天猫翻牌抽奖代码
  9. Windows/Linux服务器监控软件推荐
  10. 行楷练习2 横连点、纵连点、附钩横、连横