相关依赖
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.0.0-android</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
<!-- hutool工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.22</version>
</dependency>
Collections
1. 正序与反序,排序只需要记住下面的一行代码,注意反向排序的 reversed 方法,注意 reversed ,注意 reversed !
Collections.sort(users, Comparator.comparing(UserVO::getAge).reversed());
- 最大值与最小值
// 输出用户中年龄最大的
Collections.max(users, Comparator.comparing(UserVO::getAge));
// 输出用户中年龄最小的
Collections.min(users, Comparator.comparing(UserVO::getAge));
- 交换位置
Collections.swap(users, 0, 1);
System.out.println(users);
数组和 list 相互转化
@Test
public void arr_to_list_test(){
// 对象数组转list
UserVO[] userArr = {
UserVO.builder().age(10).build(),
UserVO.builder().age(20).build()
};
List<UserVO> users = Arrays.stream(userArr).collect(Collectors.toList());
// 基本数据类型的数组转list
int[] intArr = {1, 2, 3};
List<Integer> intList = Arrays.stream(intArr).boxed().collect(Collectors.toList());
}
@Test
public void list_to_arr_test(){
UserVO[] array = users.toArray(new UserVO[0]);
Arrays.stream(array).forEach(System.out::println);
}
CollectionUtils
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
// 集合的交并差补
@Test
public void testCollectionUtils_union_intersection_disjunction() {
ArrayList<Integer> list1 = Lists.newArrayList(1, 2, 3, 4);
ArrayList<Integer> list2 = Lists.newArrayList(3, 4, 5, 6);
// union
System.out.println(CollectionUtils.union(list1,list2));
// intersection
System.out.println(CollectionUtils.intersection(list1,list2));
// disjunction
System.out.println(CollectionUtils.disjunction(list1,list2));
// subtract
System.out.println(CollectionUtils.subtract(list1,list2));
}
Lists
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>32.0.0-android</version>
</dependency>
@Test
public void testLists_init() {
ArrayList<?> list = Lists.newArrayList();
Lists.newArrayListWithCapacity(10);
ArrayList<Integer> list2 = Lists.newArrayList(1, 2, 3);
Lists.newCopyOnWriteArrayList(Lists.newArrayList(1, 2, 3));
}
@Test
public void testLists_cartesian() {
ArrayList<Integer> list1 = Lists.newArrayList(1, 2, 3);
ArrayList<Integer> list2 = Lists.newArrayList(11,22,33);
List<List<Integer>> result = Lists.cartesianProduct(list1, list2);
System.out.println(result);
}
@Test
public void testLists_partition() {
ArrayList<Integer> list = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8);
List<List<Integer>> result = Lists.partition(list, 3);
System.out.println(result);
}
@Test
public void testLists_transform() {
// transform 遍历的时候用的都是原来的列表的数据,所以是个坑,不用他
ArrayList<Result> srcList = Lists.newArrayList(new Result(1, "张三"), new Result(2, "李四"));
List<String> transformList = Lists.transform(srcList, Result::getName);
System.out.println(transformList);
System.out.println(srcList);
srcList.get(0).setName("王五");
System.out.println(transformList);
}
Objects
@Test
public void testObjects_null() {
Integer num = null;
if (Math.random() > 0.5) {
num = 1;
}
System.out.println(Objects.isNull(num));
System.out.println(Objects.nonNull(num));
Objects.requireNonNull(num, "num 不能为空");
}
StringUtils
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.9</version>
</dependency>
常用方法
@Test
public void testStringUtils() {
String destStr = "abbbbbbbc";
// 转大写
System.out.println(StringUtils.upperCase(destStr, Locale.ROOT));
// 转小写
System.out.println(StringUtils.lowerCase(destStr, Locale.ROOT));
// 首字母大写
System.out.println(StringUtils.capitalize(destStr));
// 首字母小写
System.out.println(StringUtils.uncapitalize(destStr));
// 中间部分省略,并用省略字符串替换掉,并指定总长度
System.out.println(StringUtils.abbreviateMiddle(destStr,"...",5));
// 如果字符串不以指定后缀结尾,则追加后缀。
System.out.println(StringUtils.appendIfMissing(destStr,"_t"));
// 将字符串居中对齐。设置总长度,并指定两边是什么字符
System.out.println(StringUtils.center(destStr,15,'=')); // ===abbbbbbbc===
// chomp 删除掉字符串结尾的换行符
System.out.println(StringUtils.chomp(destStr));
// 比较两个字符串的大小。
System.out.println(StringUtils.compare("9","8"));
// countMatches:计算字符串中指定子串出现的次数。
System.out.println(StringUtils.countMatches("abca","a"));
// defaultIfBlank:如果字符串为空或只包含空格,则返回默认值。
System.out.println(StringUtils.defaultIfBlank(null,"abc"));
// deleteWhitespace:删除字符串中的所有空格字符。
System.out.println(StringUtils.deleteWhitespace(" a b c "));
// getCommonPrefix:获取多个字符串的共同前缀。
System.out.println(StringUtils.getCommonPrefix("bo_abc","bo_book","bo_paper"));
// indexOf:获取子串在字符串中第一次出现的位置索引。
System.out.println(StringUtils.indexOf("axbcdef","xb"));
// lastIndexOf:获取子串在字符串中最后一次出现的位置索引。
System.out.println(StringUtils.lastIndexOf("axbcdefxbxyz", "xb"));
// join:将数组中的元素连接成一个字符串。注意:必须声明为对象类型的数组,不能是基本数据类型的
Integer[] ints = {1, 2, 3, 4};
System.out.println(StringUtils.join(ints,","));
// containsIgnoreCase:不区分大小写地检查字符串是否包含指定内容。
System.out.println(StringUtils.containsIgnoreCase("sbc","B"));
// isAlpha:检查字符串是否只包含字母字符。
System.out.println(StringUtils.isAlpha("1abc"));
// isNumeric:检查字符串是否只包含数字字符。
System.out.println(StringUtils.isNumeric("383282"));
// joinWith:使用指定分隔符连接字符串数组。
System.out.println(StringUtils.joinWith(",","a","b"));
// left 从左边起,取几个字符
System.out.println(StringUtils.left("abc",1));
// right 从右边起,取几个字符
System.out.println(StringUtils.right("abc",1));
// leftPad:在字符串左侧填充指定字符至指定长度。
System.out.println(StringUtils.leftPad("abc",5));
// reverse:反转字符串。
System.out.println(StringUtils.reverse("abc"));
}
Optional
Optional 用法:
用法1
替换掉 if(xxx!=null) ,存在时进行处理
Optional.ofNullable(property).ifPresent(p -> p.setType("String"));
// 下面是源码
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
用法2
为空时进行处理
// 为空时创建一个空对象
Optional.ofNullable(property).orElse(new PropertyBean());
// 为空时传入 supply 进行处理
Optional.ofNullable(property).orElseGet(() -> {
PropertyBean bean = new PropertyBean();
bean.setType("abc");
return bean;
});
// 下面是源码
public T orElseGet(Supplier<? extends T> other) {
return value != null ? value : other.get();
}
用法3
对拿到的对象进行转换
PropertyBean bean = null;
// 如果 bean 为null 时,获取 orElse 中的值
System.out.println(Optional.ofNullable(bean).map(PropertyBean::getDesc).orElse("a"));
读Excel
依赖
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>4.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>4.1.2</version>
</dependency>
package com.x.practise.utils;
import cn.hutool.core.bean.BeanUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import java.io.FileInputStream;
import java.lang.reflect.Field;
import java.net.URISyntaxException;
import java.nio.file.Paths;
import java.util.*;
public class ExcelReader {
public static Map<String, Map<Integer, String>> sheetHeaderMap = Maps.newHashMap();
public static void main(String[] args){
String pathStr = "excel/file.xlsx";
Map<String, List<Map<?, String>>> stringListMap = readExcel(pathStr);
System.out.println(stringListMap);
}
/**
* sheet 页第一行代表 key ,下面每一行会封装成一个map,key就是第一行的值
* 每一个 sheet 页又是一个 map
*
* @param pathStr 路径
* @return
*/
public static Map<String, List<Map<?, String>>> readExcelWithHead(String pathStr) {
return readExcel(pathStr, true);
}
public static Map<String, List<Map<?, String>>> readExcel(String pathStr) {
return readExcel(pathStr, false);
}
private static HashMap<String, List<Map<?, String>>> readExcel(String pathStr, boolean withHead) {
HashMap<String, List<Map<?, String>>> result = Maps.newHashMap();
try {
FileInputStream file = new FileInputStream(getRealPath(pathStr));
XSSFWorkbook workbook = new XSSFWorkbook(file);
Iterator<Sheet> sheetIterator = workbook.sheetIterator();
fillResult(sheetIterator, result, withHead);
file.close();
} catch (Exception e) {
return result;
}
return result;
}
/**
* 根据路径读出数据,并按照 clazz 封装每一行的数据
* 需要 sheet 第一行跟属性对应上
*
* @param excelPath
* @param clazz
* @param <T>
* @return
*/
public static <T> Map<String, List<T>> getClassNameToBeanListMap(String excelPath, Class<T> clazz) {
Map<String, List<T>> classMap = Maps.newHashMap();
Optional.ofNullable(ExcelReader.readExcelWithHead(excelPath)).map(m -> {
m.forEach((key, value) -> {
ArrayList<T> newList = Lists.newArrayList();
m.get(key).forEach(e -> {
try {
newList.add(BeanUtil.fillBeanWithMap(e, clazz.newInstance(), true));
} catch (InstantiationException | IllegalAccessException ex) {
throw new RuntimeException(ex);
}
});
classMap.put(key, newList);
});
return m;
});
return classMap;
}
/**
* 根据传入的类型得到整个Excel的属性结构
*/
public static <T> Map<String, List<T>> getClassNameToBeanListMapWithReflect(String excelPath, Class<T> clazz) {
Map<String, List<T>> classMap = Maps.newHashMap();
ExcelReader.readExcel(excelPath).forEach((key, list)->{
ArrayList<T> newList = Lists.newArrayList();
list.forEach(e -> {
try {
newList.add(BeanUtil.fillBeanWithMap(numberToFieldMap(clazz, e), clazz.newInstance(), true));
} catch (InstantiationException | IllegalAccessException ex) {
throw new RuntimeException(ex);
}
});
classMap.put(key, newList);
});
return classMap;
}
private static <T> HashMap<String, String> numberToFieldMap(Class<T> clazz, Map<?, String> e) {
Field[] declaredFields = clazz.getDeclaredFields();
HashMap<String,String > newMap = Maps.newHashMap();
e.forEach((k, v)->{
newMap.put(declaredFields[(Integer) k].getName(), v);
});
return newMap;
}
private static void fillResult(Iterator<Sheet> sheetIterator,
HashMap<String, List<Map<?, String>>> result, boolean withHead) {
while (sheetIterator.hasNext()) {
XSSFSheet currentSheet = (XSSFSheet) sheetIterator.next();
result.put(currentSheet.getSheetName(), getRowList(currentSheet, withHead));
}
}
private static ArrayList<Map<?, String>> getRowList(XSSFSheet currentSheet, boolean withHead) {
int startIndex = withHead ? 1 : 0;
ArrayList<Map<?, String>> rowList = Lists.newArrayList();
for (int i = startIndex; i <= currentSheet.getLastRowNum(); i++) {
rowList.add(getRowMap(currentSheet, withHead ? getHeaderMap(currentSheet) : null, i));
}
return rowList;
}
public static Map<Integer, String> getHeaderMap(XSSFSheet currentSheet) {
return Optional.ofNullable(sheetHeaderMap.get(currentSheet.getSheetName())).orElseGet(() -> {
XSSFRow row = currentSheet.getRow(0);
HashMap<Integer, String> headerMap = Maps.newHashMap();
for (int j = 0; j < row.getLastCellNum(); j++) {
XSSFCell cell = row.getCell(j);
headerMap.put(j, cell.toString());
}
sheetHeaderMap.put(currentSheet.getSheetName(), headerMap);
return headerMap;
});
}
private static HashMap<?, String> getRowMap(XSSFSheet currentSheet,
Map<Integer, String> headerMap, int i) {
XSSFRow row = currentSheet.getRow(i);
HashMap<Object, String> rowMap = Maps.newHashMap();
for (int j = 0; j < row.getLastCellNum(); j++) {
XSSFCell cell = row.getCell(j);
rowMap.put(Objects.isNull(headerMap) ? j : headerMap.get(j), cell.toString());
}
return rowMap;
}
private static String getRealPath(String pathStr) throws URISyntaxException {
return Paths.get(Thread.currentThread().getContextClassLoader().getResource(pathStr).toURI()).toString();
}
}
package com.x.practise;
import lombok.Data;
@Data
public class PropertyBean {
private String type;
private String name;
private Boolean required;
private String desc;
}
package com.x.practise.utils;
import com.sun.org.apache.xml.internal.utils.URI;
import com.x.practise.PropertyBean;
import com.x.practise.template.DTO;
import jdk.nashorn.internal.runtime.regexp.joni.encoding.CharacterType;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.Map;
public class Main {
public static final String PATH = "excel/file.xlsx";
public static final String OUTPUT_PATH = "src/main/resources/output/xxx.java";
public static void main(String[] args) throws URISyntaxException {
Map<String, List<PropertyBean>> classMap = ExcelReader.getClassNameToBeanListMapWithReflect(PATH, PropertyBean.class);
System.out.println(classMap);
classMap.forEach((className, list) -> {
StringBuilder sb = new StringBuilder();
list.forEach(e->{
sb.append(String.format(DTO.PROPERTY_TEMPLATE, e.getDesc(), e.getRequired(), e.getType(), e.getName()));
});
String toWrite = String.format(DTO.TEMPLATE, className, sb);
try {
Files.write(Paths.get(OUTPUT_PATH), toWrite.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE);
} catch ( IOException e) {
throw new RuntimeException(e);
}
});
}
}
Files
public static final String OUTPUT_PATH = "src/main/resources/output/xxx.java";
Files.write(Paths.get(OUTPUT_PATH), toWrite.getBytes(StandardCharsets.UTF_8), StandardOpenOption.CREATE);
Hutool
依赖
<!-- hutool工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.7.22</version>
</dependency>
BeanUtil
BeanUtil.fillBeanWithMap(e, new PropertyBean(), true);
Mocktio
依赖
<dependencies>
<!--导入Mockito单元测试依赖-->
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
<scope>test</scope>
</dependency>
<!--导入junit单元测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>