java返给前端ECharts的格式
1. 返回值:值对象(Value Object)
1. 只需要key Value 格式的VO
KvVO
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
@Data
public class KvVO<T> {
@ApiModelProperty(value = "K")
private String key;
@ApiModelProperty(value = "V")
private T value;
public KvVO(T value, String key) {
this.key = key;
this.value = value;
}
public KvVO() {
}
}
2. 带X轴和Y轴的VO
X轴可以是Stirng类型的List,
Y轴是数值,不过Y轴的数据 需要和X轴有对应关系
DataVO
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.ArrayList;
import java.util.List;
@Data
public class DataVO<T> {
//如果是多个Y轴,就需要一个List,相当于一个X轴对应多个Y轴的数值
@ApiModelProperty(value = "数值")
private List<T> data = new ArrayList<>();
@ApiModelProperty(value = "名称")
private String name;
public DataVO(List<T> data) {
this.data = data;
}
public DataVO(List<T> data, String name) {
this.data = data;
this.name = name;
}
public DataVO() {
}
}
3. 带标签的返回值
ChartVO
import com.fasterxml.jackson.annotation.JsonProperty;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.util.LinkedList;
import java.util.List;
@Data
public class ChartVO<T> {
//这里的三个DataVO就是上边的DataVO
@ApiModelProperty(value = "标签")
private DataVO<String> legend = new DataVO<>();
@ApiModelProperty(value = "x轴")
@JsonProperty("xAxis")
private DataVO<String> xAxis = new DataVO<>();
@ApiModelProperty(value = "统计图数据", notes = "Y轴数据")
private List<DataVO<T>> series = new LinkedList<>();
}
2. 业务对象BO:(Business Object)
这里的例子是区县,也可以是别的根据自己的业务可以灵活修改
1. 只有区县,不带标签
AreaBO
import lombok.Data;
/**
* 有区域,无标签
*/
@Data
public class AreaBO {
/**
* 数量
*/
private Integer num;
/**
* 名称
*/
private String name;
/**
* 所属区县
*/
private String homeArea;
public AreaBO() {
}
public AreaBO(Integer num, String name) {
this.num = num;
this.name = name;
}
public AreaBO(Integer num, String name, String homeArea) {
this.num = num;
this.name = name;
this.homeArea = homeArea;
}
}
2. 字符串类型的key value BO
KvBO
import io.swagger.annotations.ApiModelProperty;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @Author dreamer
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class KvBO {
@ApiModelProperty(value = "K")
private String key;
@ApiModelProperty(value = "V")
private String value;
@ApiModelProperty(value = "name")
private String name;
@ApiModelProperty(value = "remark")
private String remark;
public KvBO(String key, String value) {
this.key = key;
this.value = value;
}
}
3. 带标签、带区县的BO
LegendAreaBO
import lombok.Data;
@Data
public class LegendAreaBO {
/**
* 数量
*/
private double num;
/**
* 名称
*/
private String name;
/**
* 标签
*/
private String legend;
/**
* 所属区县
*/
private String homeArea;
public LegendAreaBO() {
}
public LegendAreaBO(Double num, String name, String legend) {
this.num = num;
this.name = name;
this.legend = legend;
}
public LegendAreaBO(Double num, String name, String legend,String homeArea) {
this.num = num;
this.name = name;
this.legend = legend;
this.homeArea = homeArea;
}
}
4. 带标签,但没有区县的BO
LegendNameBO
import lombok.Data;
@Data
public class LegendNameBO {
/**
* 数量
*/
private double num;
/**
* 名称
*/
private String name;
/**
* 标签
*/
private String legend;
public LegendNameBO() {
}
public LegendNameBO(Double num, String name) {
this.num = num;
this.name = name;
}
public LegendNameBO(Double num, String name, String legend) {
this.num = num;
this.name = name;
this.legend = legend;
}
}
3. EChartsUtil 工具
1. 汇总主城区的方法
/**
* 主城区
*/
public static ChartVO<Integer> areaBO(List<AreaBO> bo) {
//汇总主城区数量
int sum = bo.stream()
.filter(e -> BusinessConstant.mainArea.contains(e.getHomeArea()))
.mapToInt(AreaBO::getNum)
.sum();
bo.removeIf(e -> BusinessConstant.mainArea.contains(e.getHomeArea()));
//添加主城区数量
bo.add(0, new AreaBO(sum, "主城区"));
ChartVO<Integer> chart = new ChartVO<>();
//汇总x轴
List<String> xAxis = bo.stream()
.filter(e -> GasStringUtil.isNotBlank(e.getName()))
.map(AreaBO::getName)
.distinct()
.collect(Collectors.toList());
chart.setXAxis(new DataVO<>(xAxis));
//汇总数据
List<Integer> series = bo.stream()
.filter(e -> GasStringUtil.isNotBlank(e.getName()))
.map(AreaBO::getNum)
.collect(Collectors.toList());
chart.getSeries().add(new DataVO<>(series));
return chart;
}
/**
* 全市 + 主城区
*/
public static ChartVO<Integer> areaBOAllCity(List<AreaBO> bo) {
ChartVO<Integer> chart = areaBO(bo);
chart.getXAxis().getData().add(0, "全市");
chart.getSeries().forEach(e -> {
Integer sum = e.getData().stream()
.mapToInt(d -> d)
.sum();
e.getData().add(0, sum);
});
return chart;
}
2. List 转 Map
/**
* KvBO转Map
*/
public static Map<String, String> kvToMap(List<KvBO> list) {
Map<String, String> map = list.stream()
.collect(Collectors.toMap(KvBO::getKey, KvBO::getValue));
return map;
}
3. 标签 + X轴 + Y轴
/**
* 标签 + X轴 + Y轴
*/
public static ChartVO legendNameBO(List<LegendNameBO> bo) {
ChartVO chart = new ChartVO<>();
//汇总标签
List<String> legend = bo.stream()
.filter(e -> GasStringUtil.isNotBlank(e.getLegend()))
.map(LegendNameBO::getLegend)
.distinct()
.collect(Collectors.toList());
chart.setLegend(new DataVO<>(legend));
//汇总x轴
List<String> xAxis = bo.stream()
.filter(e -> GasStringUtil.isNotBlank(e.getName()))
.map(LegendNameBO::getName)
.distinct()
.collect(Collectors.toList());
chart.setXAxis(new DataVO<>(xAxis));
//汇总数据
legend.forEach(e -> {
List<Double> series = bo.stream()
.filter(y -> GasObjectUtil.equal(e, y.getLegend()) && GasStringUtil.isNotEmpty(y.getName()))
.map(LegendNameBO::getNum)
.collect(Collectors.toList());
chart.getSeries().add(new DataVO<>(series, e));
});
return chart;
}
/**
* 县级 带标签
*/
public static ChartVO legendNameBOEnt(List<LegendNameBO> bo, String area) {
if (null == area || "".equals(area)) {
area = "区域为空";
}
ChartVO<Double> chart = legendNameBO(bo);
if (GasCollectionUtil.isEmpty(chart.getSeries())) return chart;
chart.getSeries().forEach(e -> {
double sum = e.getData().stream()
.mapToDouble(d -> d)
.sum();
e.getData().add(0, sum);
});
chart.getXAxis().getData().add(0, area);
return chart;
}
4. 柱形图、折线图
/**
* KvBO 柱形图 折线图
*/
public static ChartVO kvBO(List<KvBO> bo) {
ChartVO chart = new ChartVO<>();
//汇总x轴
List<String> xAxis = bo.stream()
.filter(e -> GasStringUtil.isNotBlank(e.getKey()))
.map(KvBO::getKey)
.distinct()
.collect(Collectors.toList());
chart.setXAxis(new DataVO<>(xAxis));
//汇总数据
List<Double> series = bo.stream()
.filter(e -> GasStringUtil.isNotBlank(e.getKey()))
.map(e -> GasConvertUtil.toDouble(e.getValue()))
.collect(Collectors.toList());
chart.getSeries().add(new DataVO<>(series));
return chart;
}
5. KvBO 转换为饼图
/**
* KvBO 转换为饼图
*/
public static ChartVO kvBOPie(List<KvBO> bo) {
ChartVO chart = new ChartVO();
//汇总标签
List<String> legend = bo.stream()
.map(KvBO::getKey)
.collect(Collectors.toList());
chart.setLegend(new DataVO<>(legend));
List<PieDataVO> pieData = bo.stream()
.map(e -> new PieDataVO<>(e.getKey(), e.getValue()))
.collect(Collectors.toList());
chart.setSeries(GasListUtil.toList(new DataVO<>(pieData)));
return chart;
}
4. demo演示
Controller
@Api(tags = {"管道气企业概况"})
@Slf4j
@Validated
@RestController
@RequestMapping("enterprise")
public class EnterpriseController {
@Resource
private EnterpriseInfoService enterpriseInfoService;
@ApiOperation(value = "统计图-管龄统计")
@GetMapping("/pipeAge")
public R<ChartVO<BigDecimal>> pipeCounty(@Validated AreaDTO dto) {
ChartVO<BigDecimal> vo = enterpriseInfoService.pipeCounty(dto);
return R.ok(vo);
}
}
参数 AreaDTO
import com.gas.constants.DictConstant;
import com.gas.valid.dict.Dict;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.experimental.Accessors;
import java.util.List;
/**
* 区域code
* @author sunyongchao
*/
@Data
@Accessors(chain = true)
public class AreaDTO {
@ApiModelProperty(value = "行政区域; 数据字典 code= " + DictConstant.AREA, example = DictConstant.LUBEI_DISTRICT)
@Dict(value = {DictConstant.AREA}, message = "区域,不在取值范围内")
private String area;
@ApiModelProperty(value = "行政区域数组", hidden = true)
private List<String> areaArray;
@ApiModelProperty(value = "行政区域name", hidden = true)
private String areaName;
@ApiModelProperty(value = "企业Id数组", hidden = true)
private List<Long> enterpriseIds;
@ApiModelProperty(value = "单位Code", hidden = true)
private String deptCode;
}
校验AreaDTO的类
import com.gas.common.basic.dept.service.DeptService;
import com.gas.common.gas.dict.util.GasDictUtil;
import com.gas.constants.BusinessConstant;
import com.gas.dto.AreaDTO;
import com.gas.utils.GasDeptUtil;
import com.gas.utils.string.GasStringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
/**
* @author 孙永潮
*/
@Service
@Slf4j
public class AreaDtoValid {
@Resource
private DeptService deptService;
private static AreaDtoValid util;
//初始化service
@PostConstruct
public void initialization() {
// /ɪˌnɪʃəlɪˈzeɪʃn/
util = this;
util.deptService = this.deptService;
}
/**
* 区域 校验
*/
public static AreaDTO areaArrayValid(AreaDTO dto){
if (GasStringUtil.isNotBlank(dto.getArea())){
dto.setAreaArray(GasStringUtil.split(dto.getArea(),","));
//洋哥的通用方法: 根据字典code 查字典name
dto.setAreaName(GasDictUtil.findNameByCode(dto.getArea()));
//获取 单位Code
dto.setDeptCode(util.deptService.getDeptCode(dto));
//李唯的通用方法: 根据区域 获取单位下的 企业idList
dto.setEnterpriseIds(GasDeptUtil.getEnterpriseIdsByDeptArea(dto.getArea()));
if (dto.getAreaArray().equals(BusinessConstant.mainArea)){
//如果区域code为主城区,就把name设置为 主城区
dto.setAreaName("主城区");
}else if (dto.getArea().equals(GasStringUtil.join(",", BusinessConstant.mainArea))){
dto.setAreaName("主城区");
}
}
return dto;
}
/**
* 根据area获取 所属单位Code
*/
public static AreaDTO getDeptCode(AreaDTO dto){
if (GasStringUtil.isNotBlank(dto.getArea())){
dto.setDeptCode(util.deptService.getDeptCode(dto));
}
return dto;
}
}
Service
public interface EnterpriseInfoService {
//统计图-管龄统计(市级、县级)
ChartVO<BigDecimal> pipeCounty(AreaDTO dto);
}
Service impl (implementation)
@Slf4j
@Service
public class EnterpriseInfoServiceImpl implements EnterpriseInfoService {
@Resource
private EnterpriseInfoMapper mapper;
/**
* 柱形图-管龄统计(市级、县级)
*/
@Override
public ChartVO<BigDecimal> pipeCounty(AreaDTO dto) {
if (GasStringUtil.isBlank(dto.getArea())){
//如果区县为空,查全市
LinkedList<LabelNameBo> bo = mapper.pipe(dto);
//m(米) 转成 km(千米)
bo.forEach(e -> e.setNum(GasNumberUtil.div(e.getNum(),1000,2)));
ChartVO<BigDecimal> chart = layoutBigDecimal(bo);
return chart;
}else {
LinkedList<LabelNameBo> bo = mapper.pipe(AreaDtoValid.areaArrayValid(dto));
//m(米) 转为 km(千米)
bo.forEach(e -> e.setNum(GasNumberUtil.div(e.getNum(),1000,2)));
ChartVO<BigDecimal> chart = layoutBigDecimal(bo);
return chart;
}
}
}
Mapper
public interface EnterpriseInfoMapper {
//统计图-管龄统计(市级 和 县级)
LinkedList<LabelNameBo> pipe(AreaDTO dto);
}
Mapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gas.enterpriseSituation.pipeGasEnterprise.mapper.EnterpriseInfoMapper">
<!-- 统计图-管龄统计 -->
<select id="pipe" resultType="com.gas.enterpriseSituation.pipeGasEnterprise.bo.LabelNameBo">
SELECT SUM(e.num) AS num
, e.pipeAgeCode AS label
, e.name
FROM (
SELECT IFNULL(SUM(PIPE_LENGTH),0) AS num, gd.DICT_CODE AS pipeAgeCode, gd.DICT_NAME AS name
FROM TB_BASIC_PIPE p,
GAS_DICT gd
WHERE 0 <= datediff(year, BUILD_DATE, curdate())
AND datediff(year, BUILD_DATE, curdate()) < 5
--AND PIPE_STATUS = 2
AND gd.DICT_CODE = (${@com.gas.constants.DictConstant@PIPE_AGE_0_5})
<if test="enterpriseIds != null and enterpriseIds.size()>0 and enterpriseIds.get(0) != ''">
AND p.DEPT_ID IN
<foreach collection="enterpriseIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
AND gd.DELETE_FLAG = 1
AND gd.GENERAL_STATUS = 1
GROUP BY
gd.DICT_CODE,
gd.DICT_NAME
UNION ALL
SELECT IFNULL(SUM(PIPE_LENGTH),0) AS num, gd.DICT_CODE AS pipeAgeCode, gd.DICT_NAME AS name
FROM TB_BASIC_PIPE p,
GAS_DICT gd
WHERE 5 <= datediff(year, BUILD_DATE, curdate())
AND datediff(year, BUILD_DATE, curdate()) < 10
--AND PIPE_STATUS = 2
AND gd.DICT_CODE = (${@com.gas.constants.DictConstant@PIPE_AGE_5_10})
AND gd.DELETE_FLAG = 1
AND gd.GENERAL_STATUS = 1
<if test="enterpriseIds != null and enterpriseIds.size()>0 and enterpriseIds.get(0) != ''">
AND p.DEPT_ID IN
<foreach collection="enterpriseIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
GROUP BY
gd.DICT_CODE,
gd.DICT_NAME
UNION ALL
SELECT IFNULL(SUM(PIPE_LENGTH),0) AS num, gd.DICT_CODE AS pipeAgeCode, gd.DICT_NAME AS name
FROM TB_BASIC_PIPE p,
GAS_DICT gd
WHERE 10 <= datediff(year, BUILD_DATE, curdate())
AND datediff(year, BUILD_DATE, curdate()) < 15
--AND PIPE_STATUS = 2
AND gd.DICT_CODE = (${@com.gas.constants.DictConstant@PIPE_AGE_10_15})
AND gd.DELETE_FLAG = 1
AND gd.GENERAL_STATUS = 1
<if test="enterpriseIds != null and enterpriseIds.size()>0 and enterpriseIds.get(0) != ''">
AND p.DEPT_ID IN
<foreach collection="enterpriseIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
GROUP BY
gd.DICT_CODE,
gd.DICT_NAME
UNION ALL
SELECT IFNULL(SUM(PIPE_LENGTH),0) AS num, gd.DICT_CODE AS pipeAgeCode, gd.DICT_NAME AS name
FROM TB_BASIC_PIPE p,
GAS_DICT gd
WHERE (15 <= datediff(year, BUILD_DATE, curdate()))
AND (datediff(year, BUILD_DATE, curdate()) < 20)
--AND PIPE_STATUS = 2
AND gd.DICT_CODE = (${@com.gas.constants.DictConstant@PIPE_AGE_15_20})
AND gd.DELETE_FLAG = 1
AND gd.GENERAL_STATUS = 1
<if test="enterpriseIds != null and enterpriseIds.size()>0 and enterpriseIds.get(0) != ''">
AND p.DEPT_ID IN
<foreach collection="enterpriseIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
GROUP BY
gd.DICT_CODE,
gd.DICT_NAME
UNION ALL
SELECT IFNULL(SUM(PIPE_LENGTH),0) AS num, gd.DICT_CODE AS pipeAgeCode, gd.DICT_NAME AS name
FROM TB_BASIC_PIPE p,
GAS_DICT gd
WHERE 20 <= datediff(year, BUILD_DATE, curdate())
AND datediff(year, BUILD_DATE, curdate()) < 25
--AND PIPE_STATUS = 2
AND gd.DICT_CODE = (${@com.gas.constants.DictConstant@PIPE_AGE_20_25})
AND gd.DELETE_FLAG = 1
AND gd.GENERAL_STATUS = 1
<if test="enterpriseIds != null and enterpriseIds.size()>0 and enterpriseIds.get(0) != ''">
AND p.DEPT_ID IN
<foreach collection="enterpriseIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
GROUP BY
gd.DICT_CODE,
gd.DICT_NAME
UNION ALL
SELECT IFNULL(SUM(PIPE_LENGTH),0) AS num, gd.DICT_CODE AS pipeAgeCode, gd.DICT_NAME AS name
FROM TB_BASIC_PIPE p,
GAS_DICT gd
WHERE 25 <= datediff(year, BUILD_DATE, curdate())
AND PIPE_STATUS = 2
AND gd.DICT_CODE = (${@com.gas.constants.DictConstant@PIPE_AGE_25_ABOVE})
AND gd.DELETE_FLAG = 1
AND gd.GENERAL_STATUS = 1
<if test="enterpriseIds != null and enterpriseIds.size()>0 and enterpriseIds.get(0) != ''">
AND p.DEPT_ID IN
<foreach collection="enterpriseIds" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</if>
GROUP BY
gd.DICT_CODE,
gd.DICT_NAME
UNION ALL
SELECT 0 AS num
, gd.DICT_CODE AS pipeAgeCode
, gd.DICT_NAME AS name
FROM GAS_DICT gd
WHERE gd.DICT_CODE LIKE CONCAT(${@com.gas.constants.DictConstant@THE_PIPE_AGE},'0%')
AND gd.DELETE_FLAG = 1
AND gd.GENERAL_STATUS = 1
) e
GROUP BY e.pipeAgeCode
, e.name
</select>
</mapper>
上边校验AreaDTO里边有几个封装好的静态方法
GasDictUtil.findNameByCode
/**
* @Author zhaoyang
* @create 2022/1/5 8:39
*/
@Component
public class GasDictUtil {
@Resource
private GasDictService gasDicService;
static GasDictUtil gasDictUtil;
@PostConstruct
public void init() {
gasDictUtil = this;
gasDictUtil.gasDicService = gasDicService;
}
public static String findNameByCode(String code) {
if (GasObjectUtil.isNull(code)) {
return null;
}
String rCode = redisName(code);
String name;
Object obj = GasRedisUtil.get(rCode);
if (GasObjectUtil.isNull(obj)) {
name = gasDictUtil.gasDicService.getObj(Wrappers.lambdaQuery(GasDict.class)
.select(GasDict::getDictName)
.eq(GasDict::getDictCode, code)
.last("LIMIT 1")
, Objects::toString);
if (GasObjectUtil.isNotNull(name)){
GasRedisUtil.set(rCode, name);
}
} else {
name = obj.toString();
}
return name;
}
public static String findNameByCodes(String codes) {
if (GasObjectUtil.isNull(codes)) {
return null;
}
List<String> list = GasListUtil.toList(GasStringUtil.splitStr(codes));
String name = list.stream()
.map(e -> findNameByCode(e))
.filter(e-> GasObjectUtil.isNotNull(e))
.collect(Collectors.joining("、"));
return name;
}
/**
* 返回redis 前缀
*/
static String redisName(String code) {
return BusinessConstant.DICT + code;
}
}
获取区域所属单位的方法
GasDeptUtil.getEnterpriseIdsByDeptArea
@Component
public class GasDeptUtil {
@Resource
private DeptService deptService;
@Resource
private EnterpriseService enterpriseService;
private static GasDeptUtil util;
//初始化service
@PostConstruct
public void init() {
util = this;
util.deptService = this.deptService;
util.enterpriseService = this.enterpriseService;
}
/**
* 根据area获取单位
*/
public static List<Long> getEnterpriseIdsByDeptArea(String area) {
List<Dept> dept = util.deptService.list(Wrappers.<Dept>lambdaQuery()
.eq(Dept::getHomeArea, area)
.eq(Dept::getDeleteFlag, BusinessConstant.ON));
if (dept.isEmpty()) return new ArrayList<>();
List<Enterprise> enterprises = util.enterpriseService.list(Wrappers.<Enterprise>lambdaQuery()
.eq(Enterprise::getParentCode, dept.get(0).getDeptCode())
.eq(Enterprise::getDeleteFlag, BusinessConstant.ON));
if (enterprises.isEmpty()) return new ArrayList<>();
return enterprises.stream()
.map(Enterprise::getId)
.collect(Collectors.toList());
}
}
业务专用常量
public interface BusinessConstant {
/**
* 主城区字典code
*/
List<String> mainArea = GasListUtil.toList(DictConstant.LUBEI_DISTRICT, DictConstant.LUNAN_DISTRICT, DictConstant.GAOXIN_DISTRICT);
}
字典常量
/**
* 字典常量
*/
public interface DictConstant {
/**
* 所属区县
*/
String AREA = "100008";
/**
* 所属区县-路北区
*/
String LUBEI_DISTRICT = "1000080001";
/**
* 所属区县-路南区
*/
String LUNAN_DISTRICT = "1000080002";
/**
* 所属区县-高新开发区
*/
String GAOXIN_DISTRICT = "1000080007";
}
继承的hutool工具类
package cn.hutool.core.collection;
import cn.hutool.core.comparator.PinyinComparator;
import cn.hutool.core.comparator.PropertyComparator;
import cn.hutool.core.lang.Matcher;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.PageUtil;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.RandomAccess;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.function.Consumer;
//List相关工具类(里边有好多方法,这里只引入了一个)
public class ListUtil {
/**
* 新建一个ArrayList
* Params: values – 数组
* Type parameters: <T> – 集合元素类型
* Returns: ArrayList对象
*/
@SafeVarargs
public static <T> ArrayList<T> toList(T... values) {
return (ArrayList<T>) list(false, values);
}
}
走好自己选择的路,而不是选择好走的路,好的代码像粥一样,都是慢慢熬出来的。