Windows命令
netstart -ano
// 查看已被占用端口及对应进程
regedit
// 打开注册表
mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion=11.1.0.6.0 -Dpackaging=jar -Dfile=ojdbc14.jar
// 导入jar包到Maven库。
// rabbitmq 用管理员打开cmd
rabbitmq-service stop
rabbitmq-service remove
rabbitmq-service install
rabbitmq-service start
rabbitmq-plugins enable rabbitmq_management
Linux命令
ps -ef|grep key
// 查含关键字key的正在运行的进程
kill -9 进程号
// 杀死某进程
nohup > abc.log java -jar abc.jar
// 启动jar包 日志保存在指定文件中
setsid java -jar abc.jar
java -jar abc.jar
lsof -i
// 查看端口占用情况
service DmServiceDMSERVER stop
service DmServiceDMSERVER start
// 重启达梦库
tab
// 补全
ll / ls
// 查看当前目录下文件
pwd
// 查看当前目录
chmod +x abc.sh
// 将abc.sh赋可执行权限
chmod -v u+w /etc/profile
// 如果/etc/profile文件不可编辑,需要修改为可编辑
vim /etc/profile
// 修改环境变量
export PATH=$PATH:/home/uusama/mysql/bin
//
source /etc/profile
date -s "2021-9-22 14:55:00"
// 修改系统时间
shutdown -h 10 ‘I will shutdown after 10 mins’
// 10min后关机
shutdown -h now
// 立刻关机
shutdown -h 20:25
// 系统定时关机
shutdown -r now
// 立刻重启
输入 vim filename进入文件编辑模式。
1、按"i"建进入文件编辑模式,按"ESC"退出文件编辑模式。
2、按"ESC"退出编辑模式后,按 “:",
"q"为文件并未进行修改,离开;
"wq"为文件经过修改,保存离开;
"q!"为文件经过修改,不保存强制离开。
3、按"ESC"退出编辑模式后,按 “:”,并输入"/name",可以在文件中寻找到包含name位置。
4、按"ESC"退出编辑模式后,"dd"表示剪切某一行代码,"d"表示剪切某一块代码,"p"表示粘贴某一行代码。
SQL
一些语法
xxx is not null
// 某字段不为空
trim(to_char('1001.0','9999'))
// 输出1001
to_number('1001', '9999999')
// 将‘1001’转成1001
CONCAT(CONCAT('%',#{name}),'%')
// 模糊查询
startTime between trunc(sysdate) and trunc(sysdate)+1
// 限制查询今日数据
yyyy-mm-dd hh24:mi:ss
>
<
ltrim(rtrim(a.systemname))
ltrim('%',rtrim('d','%'))
???
(case t.status_code when '200' then 0 else 1 end) as resultFlag
select distinct cast(t.api_id as varchar) as transName
nvl(max(ID), 0)
// 判空,赋默认值
// dm查看字符集 0 gb18030 1utf-8 2 euc-kr
select SF_GET_UNICODE_FLAG(); select UNICODE ();
DATEADD(datepart,number,date)
// 时间加减 datepart->yy年/qq季度/mm月/dd日/wk周/hh小时/mi分钟/ss秒/ms毫秒 number->数值 date->日期
限制查询结果范围
oracle:
// 限制查询结果范围
select tt2.* from
(select tt.*, rownum no from
(
select * from test
) tt
where rownum <= #{endLimit}
) tt2
where tt2.no >= #{startLimit}
mysql:
limit [startLimit] [endLimit]
partition by
select row_number() over (partition by province_id order by report_time desc) rank , a.*
from ele_transaction.forecast_prov_midlong_mea a
partition by 关键字是分析性函数的一部分,可以返回一个分组的每一条记录,并且可以对分组数据进行排序操作。
group by 关键字是聚合函数的一部分,它只能返回聚合之后的组的数据统计值记录。
PLSQL创建用户
1创建表空间
说明:datafile是指定创建位置,指向oracle数据库的默认位置;
autoextend 设置容量为自动增长,50M是自增的大小
create tablespace TEST
datafile 'E:/app/Administrator/oradata/orcl/TEST'
size 1M autoextend on next 50M maxsize unlimited;
2创建新用户
说明:identified by后为用户登录密码;
default tablespace为默认表空间;
profile设为系统默认;
ACCOUNT UNLOCK解锁用户;
create user TEST
identified by "123"
default tablespace TEST
profile DEFAULT
ACCOUNT UNLOCK;
3.授限
说明:分别给用户授dba权限和表空间授无限增长权限
grant dba to TEST;
grant unlimited tablespace to TEST;
JAVA
可变参数列表
Integer...
Mybatis
ArrayList类型的参数
<if test="monthList != null and monthList.size > 0">
and s.monthName in
<foreach collection="monthList" item="month" separator="," open="(" close=")">
#{month}
</foreach>
</if>
<if test="monthList == null or monthList.size == 0">
and s.forecastTime > sysdate
</if>
<insert id="insertDoubleFaultRecord" parameterType="java.util.ArrayList">
insert into JC_DB.DOUBLE_FAULT_RECORD
(ID,
FAULT_TIME
)
values
<foreach collection="doubleFaultRecordList" item="item" index="index" separator=",">
(#{item.id},
#{item.faultTimeDate}
)
</foreach>
</insert>
if内判断传参等于某字符串
<if test="onlySuccess != null and onlySuccess == '1'.toString()">
and t1.RESULT_FLAG = 0
</if>
if else
where
<choose>
<when test="d5000Id != null and d5000Id != '' and queryTime != null">
ID = #{d5000Id}
and TIME > #{queryTime}
</when>
<otherwise>
1 = 0
</otherwise>
</choose>
merge into
<update id="updateSearchInterestData" parameterType="java.lang.String">
merge into JC_DB.WXAP_SEARCH_INTEREST t1
using (
select #{searchValue} CONTENT
from dual
) t2
on t1.CONTENT = t2.CONTENT
when not matched then
insert (t1.CONTENT, t1.COUNT)
values (#{searchValue}, 1)
when matched then
update
set t1.COUNT = t1.COUNT + 1
where t1.CONTENT = #{searchValue}
</update>
<update id="editMsgType" parameterType="com.ieslab.wechatappconfig.msgsend.entity.MsgSendType">
merge into JC_DB.MSG_SEND_TYPE a
using (
select #{msgSendType.eventTypeCode} EVENT_TYPE_CODE, #{msgSendType.msgTypeCode} MSG_TYPE_CODE, #{msgSendType.msgLevelCode} MSG_LEVEL_CODE
from dual
) b
on (a.EVENT_TYPE_CODE = b.EVENT_TYPE_CODE and a.MSG_TYPE_CODE = b.MSG_TYPE_CODE and a.MSG_LEVEL_CODE = b.MSG_LEVEL_CODE)
when not matched then
insert (a.EVENT_TYPE_CODE, a.MSG_TYPE_CODE, a.MSG_LEVEL_CODE, DETAIL, PARTY_ID, TAG_ID, USER_ID)
values(#{msgSendType.eventTypeCode}, #{msgSendType.msgTypeCode}, #{msgSendType.msgLevelCode}, #{msgSendType.detail}, #{msgSendType.partyId}, #{msgSendType.tagId}, #{msgSendType.userId})
when matched then
update
set DETAIL = #{msgSendType.detail},
PARTY_ID = #{msgSendType.partyId},
TAG_ID = #{msgSendType.tagId},
USER_ID = #{msgSendType.userId}
where a.EVENT_TYPE_CODE = #{msgSendType.eventTypeCode}
and a.MSG_TYPE_CODE = #{msgSendType.msgTypeCode}
and a.MSG_LEVEL_CODE = #{msgSendType.msgLevelCode}
</update>
注解
SpringBoot、Spring
@PathVariable
@RequestMapping(value = "/{path}")
public String getInterCallData(@PathVariable("path") String path, HttpServletRequest request) {
}
@RequestMapping
@RequestMapping(value="/fileUpload", produces = "application/json;charset=utf-8")
需指定produces = "application/json;charset=utf-8")
否则页面不能拿到对象。
@Value(“${paramName}:defaultValue”)
获取配置文件中定义的变量值
@Scheduled(cron = "0 */1 * * * ? ")
定时任务 项目启动类需要添加@EnableScheduling注解。
@JsonIgnoreProperties({ “xx”, “yy” })
将该注解加在实体类上,可以指定要忽略的字段
@JsonIgnore
用来忽略实体类中的某个字段
@JsonFormat(timezone = “GMT+8”, pattern = “yyyy-MM-dd HH:mm:ss”)
用来完成格式转换 例如对于Date类型字段,默认在rest返回的是long,使用该注解可以返回时间格式化字符串
@RequiredArgsConstructor
spring依赖注入常规操作使用@Autowried。当需要大量注入时,写起来不美观,可以使用在构造方法上加@Autowried的方式,也可以在类上加上@RequiredArgsConstructor注解,该注解是lombok中的,然后将依赖注入的对象加上final修饰即可。
Java内置注解
@Deprecated
标记此方法或类已经过时
MAP
map数据
compute方法
对指定key在map中的值进行操作,不管存不存在,操作完成后保存在map中。
Map<String,Integer> map = new HashMap<>();
map.put("1",1);
map.put("2",2);
map.put("3",3);
Integer integer1 = map.compute("3", (k,v) -> v+1 );
//key不管存在不在都会执行后面的函数,并保存到map中
Integer integer2 = map.compute("4", (k,v) -> {
if (v==null) return 0;
return v+1;
});
System.out.println(integer1); // 输出4
System.out.println(integer2); // 输出0
System.out.println(map.toString()); // 输出{1=1, 2=2, 3=4, 4=0}
computeIfAbsent方法
key值不存在时,执行函数,操作完成后保存在map中。
key值存在时返回当前value值。
Map<String,Integer> map = new HashMap<>();
map.put("1",1);
map.put("2",2);
map.put("3",3);
Integer integer1 = map.computeIfAbsent("3", key -> new Integer(4));//key存在返回value
Integer integer2 = map.computeIfAbsent("4", key -> new Integer(4));//key不存在执行函数存入
System.out.println(integer1); // 输出3
System.out.println(integer2); // 输出4
System.out.println(map.toString()); // 输出{1=1, 2=2, 3=3, 4=4}
computeIfPresent方法
只对已经存在key的进行操作,不存在不操作。
Map<String,Integer> map = new HashMap<>();
map.put("1",1);
map.put("2",2);
map.put("3",3);
//只对map中存在的key对应的value进行操作
Integer integer1 = map.computeIfPresent("3", (k,v) -> v+1 );
Integer integer2 = map.computeIfPresent("4", (k,v) -> {
if (v==null) return 0;
return v+1;
});
System.out.println(integer1); // 输出4
System.out.println(integer2); // 输出null
System.out.println(map.toString()); // 输出{1=1, 2=2, 3=4}
List
排序
Comparator comparator = new Comparator<TransmissionChannelCurve>() {
@Override
public int compare(TransmissionChannelCurve o1, TransmissionChannelCurve o2) {
return o1.getStartTime().compareTo(o2.getStartTime());
}
};
List<TransmissionChannelCurve> dayChannelCurveList = new ArrayList<>(dayObjectMap.values());
dayChannelCurveList.sort(comparator);
List<String> names = sgDatacenterTableNameList.stream().filter(o -> o.contains(name) && !o.contains("_TEST")).collect(Collectors.toList());
names.sort(Comparator.comparing(String::toString, Collections.reverseOrder()));
fileInteriorTrans = fileInteriorTrans.stream().filter(trans -> !noShowTaskIdSet.contains(trans.getId())).collect(Collectors.toList());
taskDetailInfoDao.getDepartmentList().stream().filter(Objects::nonNull).collect(Collectors.toList())
DateUtils
org.apache.commons.lang3.time.DateUtils
addMonths
Enum枚举类
public enum StatusCodeEnum {
SUCCESS("成功", 200),
ERROR_REQUEST_PARAM("请求参数错误", 400),
ERROR_NO_PERMISSION("无权限访问", 401),
ERROR_NO_ACCESS("禁止访问", 403),
ERROR_NO_FIND("找不到接口", 404),
ERROR_TIMEOUT("请求超时", 408),
ERROR_EXCEPTION("接口异常", 500),
;
private String memo; // 描述
private Integer code; // 状态码
private static final Map<String, StatusCodeEnum > statusInfoMap= new HashMap<>();
static {
for(StatusCodeEnum aenum: EnumSet.allOf(StatusCodeEnum .class)) {
statusInfoMap.put(aenum.getCode(), aenum);
}
}
StatusCodeEnum(String memo, Integer code) {
this.memo = memo;
this.code = code;
}
public String getMemo() {
return memo;
}
public Integer getCode() {
return code;
}
}
Future接口
Dom4j
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
XML字符串和Document对象互相转换
//字符串转为Document对象
public org.dom4j.Document StrToXMLDocment(String xmlStr) {
org.dom4j.Document document = null;
try {
document = DocumentHelper.parseText(xmlStr);
} catch (DocumentException e) {
e.printStackTrace();
}
return document;
}
//Document对象转为字符串
public String XMLDocumentToStr(Document document) {
String XMLStr = document.asXML();
return XMLStr;
}
父类
public abstract class OldMission {
protected String type; //任务种类
protected String areaType; //任务类型
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public abstract String getAreaType();
}
public class OldTransInteriorDbTask extends OldMission {
private Integer taskPfType; //
public OldTransInteriorDbTask(){
this.type = "OldTransInteriorDbTask";
}
@Override
public String getAreaType() {
return null;
}
}
Java8 Optional
Optional类的引入要求我们强制处理和避免空指针
用法1 利用返回值
使用内部的ofNullable去掉if的写法,将返回值set到其他对象
public static void main(String[] args) {
Map<Object, Object> testMap= new HashMap<>();
testMap.put("name", "ewl");
testMap.put("age", 18);
Person a = new Person();
// 使用内部的ifPresent避免了空指针异常
Optional.ofNullable(objectObjectHashMap.get("name1"))
.ifPresent(name -> a.setName(name.toString().toUpperCase()));
Optional.ofNullable(objectObjectHashMap.get("age1"))
.ifPresent(age -> a.setAge(Integer.valueOf(age.toString()) + 18));
System.out.println(a);
}
用法2 链式调用map()方法 消除多重if xxx != null 嵌套
想要实现a b c三个变量的加法乘法组合运算,但三个变量都可能为null
Integer a = getA();
if (a != null) {
Integer b = getB();
if ( b != null) {
Integer c = getC();
if ( c != null) {
return (a + b) * c;
} else return null;
} else return null;
} else return null;
Optional<Integer> result = Optional.ofNullable(getA())
.flatMap(a -> Optional.ofNullable(getB()).map( b -> a + b ))
.flatMap(sum -> Optional.ofNullable(getC()).map( c -> sum * c ))
用法3 使用ofElse 为null时返回默认值
static class UserMapper {
public static BizUser selectBizUserByEmployeeNum(String employeeNum) {
return null;
}
}
public static Integer run() {
BizUser user = UserMapper.selectBizUserByEmployeeNum("3306");
return Optional.ofNullable(user).map(BizUser::getDeptId)
.filter(deptId -> deptId.intValue() != 0).orElse(1122);
}
public static void main(String[] args) {
Integer run = run();
System.out.println(run);
}
用法4 使用orElseThrow 为null抛出异常到上层中断执行
static class UserMapper{
public static BizUser selectBizUserByEmployeeNum(String employeeNum) {
return null;
}
}
public static void main(String[] args) {
BizUser user = UserMapper.selectBizUserByEmployeeNum("3306");
Optional.ofNullable(user).map(BizUser::getDeptId).filter(deptId -> deptId.intValue() != 0)
.orElseThrow(() -> new CustomException("查询到的user为空!"));
}
用法5 使用filter完成除非空判断以外的其他判断
另外,如果你需要对返回值进行判断,比如结果是否大于某个值等,可以使用Optional的filter方法。
HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
objectObjectHashMap.put("name", "kawai");
objectObjectHashMap.put("age", 19);
//TODO 使用内部的ifPresent避免了空指针异常
Object a = Optional.ofNullable(objectObjectHashMap.get("age"))
.filter(age -> Integer.parseInt(age.toString()) >= 18).orElse(18);
System.out.println(a);
Java8 Stream
!!!注意!!!
在使用stream的时候,生成的集合的的确确就是新集合,无论你对收集的集合进行新增对象还是删除对象对原有集合都没有影响到,但是如果你对收集起来的集合里面的对象进行修改值,那么原集合中的对象的值也会发生变化,因为收集的集合里面的对象和原集合中的对象引用的地址值是一模一样的,所以当我们改变收集起来的集合对象里面的值,原集合里面的对象里面的值也一样会进行修改。这有点类似于浅拷贝,而不像深拷贝一样会生成一个新的地址,复制其所有属性值。
同样,如果对原有集合进行新增或删除对象,对新生成的集合也不会有影响;但是如果对原有集合里面的对象进行修改值,那么新生成的集合也会发生对应值的变化!!!
public static void main(String[] args) {
StationPowerOutage stationPowerOutage1 = new StationPowerOutage();
stationPowerOutage1.setOffTime(new Date());
stationPowerOutage1.setOrgId("11");
stationPowerOutage1.setRdfId("11");
StationPowerOutage stationPowerOutage2 = new StationPowerOutage();
stationPowerOutage2.setOffTime(new Date());
stationPowerOutage2.setOrgId("11");
stationPowerOutage2.setRdfId("22");
StationPowerOutage stationPowerOutage3 = new StationPowerOutage();
stationPowerOutage3.setOffTime(new Date());
stationPowerOutage3.setOrgId("33");
stationPowerOutage3.setRdfId("33");
StationPowerOutage stationPowerOutage4 = new StationPowerOutage();
stationPowerOutage4.setOffTime(new Date());
stationPowerOutage4.setOrgId("11");
stationPowerOutage4.setRdfId("44");
List<StationPowerOutage> stationPowerOutageList = new ArrayList<>();
stationPowerOutageList.add(stationPowerOutage1);
stationPowerOutageList.add(stationPowerOutage2);
stationPowerOutageList.add(stationPowerOutage3);
Map<String, List<StationPowerOutage>> orgIdAndOffTimeAndStPowerOutageListMap = stationPowerOutageList
.stream()
.collect(Collectors.groupingBy(stationPowerOutage ->
stationPowerOutage.getOrgId() + stationPowerOutage.getOffTime()));
for (List<StationPowerOutage> eachGroupPowerOutageList : orgIdAndOffTimeAndStPowerOutageListMap.values()) {
if (eachGroupPowerOutageList.size() > 1) {
stationPowerOutageList.removeAll(eachGroupPowerOutageList);
} else {
eachGroupPowerOutageList.get(0).setIsTrue(1);
}
}
stationPowerOutage2.setIsTrue(0);
stationPowerOutageList.remove(stationPowerOutage1);
stationPowerOutageList.add(stationPowerOutage4);
System.out.println(111);
}
概述
stream将要处理的元素集合看成一种流,在流的过程中,借助stream API对流中的元素进行操作。
创建
Stream可以通过集合数组创建。
- 通过 java.util.Collection.stream() 方法用集合创建流
List<String> list = Arrays.asList("a", "b", "c");
// 创建一个顺序流
// 顺序流由主线程按顺序对流执行操作
Stream<String> stream = list.stream();
// 创建一个并行流
// 内部会以多线程并行执行的方式对流进行操作,前提是流中的数据处理对顺序没有要求
Stream<String> parallelStream = list.parallelStream();
- 使用java.util.Arrays.stream(T[] array)方法用数组创建流
int[] array={1, 2, 3};
IntStream stream = Arrays.stream(array);
遍历/匹配(foreach/find/match)
public class StreamTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(7, 6, 9, 3, 8, 2, 1);
// 遍历输出符合条件的元素
list.stream().filter(x -> x > 6).forEach(System.out::println);
// 匹配第一个
Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
// 匹配任意(适用于并行流)
Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();
// 是否包含符合特定条件的元素
boolean anyMatch = list.stream().anyMatch(x -> x < 6);
System.out.println("匹配第一个值:" + findFirst.get());
System.out.println("匹配任意一个值:" + findAny.get());
System.out.println("是否存在大于6的值:" + anyMatch);
}
}
过滤(filter)
案例一:筛选出Integer集合中大于7的元素,并打印出来
public class StreamTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(6, 7, 3, 8, 1, 2, 9);
Stream<Integer> stream = list.stream();
stream.filter(x -> x > 7).forEach(System.out::println);
}
}
案例二: 筛选员工中工资高于8000的人,并形成新的集合。
public class StreamTest {
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
personList.add(new Person("Owen", 9500, 25, "male", "New York"));
personList.add(new Person("Alisa", 7900, 26, "female", "New York"));
List<String> fiterList = personList.stream().filter(x -> x.getSalary() > 8000).map(Person::getName)
.collect(Collectors.toList());
System.out.print("高于8000的员工姓名:" + fiterList);
}
}
聚合(max/min/count)
案例一:获取String集合中最长的元素。
public class StreamTest {
public static void main(String[] args) {
List<String> list = Arrays.asList("adnm", "admmt", "pot", "xbangd", "weoujgsd");
Optional<String> max = list.stream().max(Comparator.comparing(String::length));
System.out.println("最长的字符串:" + max.get());
}
}
案例二:获取Integer集合中的最大值。
public class StreamTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(7, 6, 9, 4, 11, 6);
// 自然排序
Optional<Integer> max = list.stream().max(Integer::compareTo);
// 自定义排序
Optional<Integer> max2 = list.stream().max(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o1.compareTo(o2);
}
});
System.out.println("自然排序的最大值:" + max.get());
System.out.println("自定义排序的最大值:" + max2.get());
}
}
案例三:获取员工工资最高的人。
public class StreamTest {
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
personList.add(new Person("Owen", 9500, 25, "male", "New York"));
personList.add(new Person("Alisa", 7900, 26, "female", "New York"));
Optional<Person> max = personList.stream().max(Comparator.comparingInt(Person::getSalary));
System.out.println("员工工资最大值:" + max.get().getSalary());
}
}
案例四:计算Integer集合中大于6的元素的个数。
public class StreamTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(7, 6, 4, 8, 2, 11, 9);
long count = list.stream().filter(x -> x > 6).count();
System.out.println("list中大于6的元素个数:" + count);
}
}
映射(map/flatMap)
将一个流的元素按照一定的映射规则映射到另一个流中。分为map和flatMap。
map:接收一个函数作为参数,该函数会应用到当前的每个元素上,将其映射成了一个新的元素。
flatMap:接收一个函数作为参数,将流中的每个值都换成了另一个流,然后把所有流连接成了一个流。
案例一:英文字符串数组的元素全部改为大写。整数数组每个元素+3。
```java
public class StreamTest {
public static void main(String[] args) {
String[] strArr = { "abcd", "bcdd", "defde", "fTr" };
List<String> strList = Arrays.stream(strArr).map(String::toUpperCase).collect(Collectors.toList());
List<Integer> intList = Arrays.asList(1, 3, 5, 7, 9, 11);
List<Integer> intListNew = intList.stream().map(x -> x + 3).collect(Collectors.toList());
System.out.println("每个元素大写:" + strList);
System.out.println("每个元素+3:" + intListNew);
}
}
案例二:将员工的薪资全部增加1000。
public class StreamTest {
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
personList.add(new Person("Owen", 9500, 25, "male", "New York"));
personList.add(new Person("Alisa", 7900, 26, "female", "New York"));
// 不改变原来员工集合的方式
List<Person> personListNew = personList.stream().map(person -> {
Person personNew = new Person(person.getName(), 0, 0, null, null);
personNew.setSalary(person.getSalary() + 10000);
return personNew;
}).collect(Collectors.toList());
System.out.println("一次改动前:" + personList.get(0).getName() + "-->" + personList.get(0).getSalary());
System.out.println("一次改动后:" + personListNew.get(0).getName() + "-->" + personListNew.get(0).getSalary());
// 改变原来员工集合的方式
List<Person> personListNew2 = personList.stream().map(person -> {
person.setSalary(person.getSalary() + 10000);
return person;
}).collect(Collectors.toList());
System.out.println("二次改动前:" + personList.get(0).getName() + "-->" + personListNew.get(0).getSalary());
System.out.println("二次改动后:" + personListNew2.get(0).getName() + "-->" + personListNew.get(0).getSalary());
}
}
案例三:将两个字符数组合并成一个新的字符数组。
public class StreamTest {
public static void main(String[] args) {
List<String> list = Arrays.asList("m,k,l,a", "1,3,5,7");
List<String> listNew = list.stream().flatMap(s -> {
// 将每个元素转换成一个stream
String[] split = s.split(",");
Stream<String> s2 = Arrays.stream(split);
return s2;
}).collect(Collectors.toList());
System.out.println("处理前的集合:" + list);
System.out.println("处理后的集合:" + listNew);
}
}
/**
* 设备类型可能的别名对应的设备信息枚举类Map
*/
Map<String, DeviceInfoEnum> deviceAnoNameAndDeviceInfoEnumMap = new HashMap<String, DeviceInfoEnum>() {{
put("变压器", DeviceInfoEnum.PWRTRANSFM);
put("主变", DeviceInfoEnum.PWRTRANSFM);
put("刀闸", DeviceInfoEnum.DIS);
put("隔离开关", DeviceInfoEnum.DIS);
put("开关", DeviceInfoEnum.BREAKER);
put("断路器", DeviceInfoEnum.BREAKER);
put("母线", DeviceInfoEnum.BUSBAR);
}};
// 获取缺陷内容
String defectContent = defectRecord.getContent();
// 获取设备类型对应的枚举类对象
DeviceInfoEnum deviceInfoEnum = deviceAnoNameAndDeviceInfoEnumMap
.entrySet()
.stream()
.filter(o -> defectContent.contains(o.getKey()))
.map(Map.Entry::getValue)
.findAny()
.orElse(null);
if(deviceInfoEnum == null) {
LOGGER.error("未通过缺陷内容(" + defectContent + ")获取到设备类型");
return defectRecord;
}
// 设备类型
String deviceType = deviceInfoEnum.getDeviceType();
defectRecord.setDeviceType(deviceType);
规约(reduce)
规约就是将一个流缩减成一个值,能实现对集合求和、求乘积、求最值的操作。
案例一:求Integer集合的元素之和、乘积和最大值。
public class StreamTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 3, 2, 8, 11, 4);
// 求和方式1
Optional<Integer> sum = list.stream().reduce((x, y) -> x + y);
// 求和方式2
Optional<Integer> sum2 = list.stream().reduce(Integer::sum);
// 求和方式3
Integer sum3 = list.stream().reduce(0, Integer::sum);
// 求乘积
Optional<Integer> product = list.stream().reduce((x, y) -> x * y);
// 求最大值方式1
Optional<Integer> max = list.stream().reduce((x, y) -> x > y ? x : y);
// 求最大值写法2
Integer max2 = list.stream().reduce(1, Integer::max);
System.out.println("list求和:" + sum.get() + "," + sum2.get() + "," + sum3);
System.out.println("list求积:" + product.get());
System.out.println("list求和:" + max.get() + "," + max2);
}
}
案例二:求所有员工的工资之和和最高工资。
public class StreamTest {
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
personList.add(new Person("Owen", 9500, 25, "male", "New York"));
personList.add(new Person("Alisa", 7900, 26, "female", "New York"));
// 求工资之和方式1:
Optional<Integer> sumSalary = personList.stream().map(Person::getSalary).reduce(Integer::sum);
// 求工资之和方式2:
Integer sumSalary2 = personList.stream().reduce(0, (sum, p) -> sum += p.getSalary(),
(sum1, sum2) -> sum1 + sum2);
// 求工资之和方式3:
Integer sumSalary3 = personList.stream().reduce(0, (sum, p) -> sum += p.getSalary(), Integer::sum);
// 求最高工资方式1:
Integer maxSalary = personList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),
Integer::max);
// 求最高工资方式2:
Integer maxSalary2 = personList.stream().reduce(0, (max, p) -> max > p.getSalary() ? max : p.getSalary(),
(max1, max2) -> max1 > max2 ? max1 : max2);
System.out.println("工资之和:" + sumSalary.get() + "," + sumSalary2 + "," + sumSalary3);
System.out.println("最高工资:" + maxSalary + "," + maxSalary2);
}
}
收集(collect)
把一个流收集起来,最终可以收集成一个值或是一个新的集合。
collect主要依赖java.util.stream.Collectors类内置的静态方法。
归集(toList/toSet/toMap)
public class StreamTest {
public static void main(String[] args) {
List<Integer> list = Arrays.asList(1, 6, 3, 4, 6, 7, 9, 6, 20);
List<Integer> listNew = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toList());
Set<Integer> set = list.stream().filter(x -> x % 2 == 0).collect(Collectors.toSet());
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
personList.add(new Person("Anni", 8200, 24, "female", "New York"));
Map<?, Person> map = personList.stream().filter(p -> p.getSalary() > 8000)
.collect(Collectors.toMap(Person::getName, p -> p));
System.out.println("toList:" + listNew);
System.out.println("toSet:" + set);
System.out.println("toMap:" + map);
}
}
统计(count/averaging)
- 计数:count
- 平均值:averagingInt、averagingLong、averagingDouble
- 最值:maxBy、minBy
- 求和:summingInt、summingLong、summingDouble
- 统计以上所有:summarizingInt、summarizingLong、summarizingDouble
public class StreamTest {
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
// 求总数
Long count = personList.stream().collect(Collectors.counting());
// 求平均工资
Double average = personList.stream().collect(Collectors.averagingDouble(Person::getSalary));
// 求最高工资
Optional<Integer> max = personList.stream().map(Person::getSalary).collect(Collectors.maxBy(Integer::compare));
// 求工资之和
Integer sum = personList.stream().collect(Collectors.summingInt(Person::getSalary));
// 一次性统计所有信息
DoubleSummaryStatistics collect = personList.stream().collect(Collectors.summarizingDouble(Person::getSalary));
System.out.println("员工总数:" + count);
System.out.println("员工平均工资:" + average);
System.out.println("员工工资总和:" + sum);
System.out.println("员工工资所有统计:" + collect);
}
}
分组(partitioningBy/groupingBy)
- 分区:将stream按条件分为两个Map,比如员工按薪资是否高于8000分为两部分。
- 分组:将集合分为多个Map,比如员工按性别分组。有单级分组和多级分组。
案例:将员工按薪资是否高于8000分为两部分;将员工按性别和地区分组
public class StreamTest {
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, "male", "New York"));
personList.add(new Person("Jack", 7000, "male", "Washington"));
personList.add(new Person("Lily", 7800, "female", "Washington"));
personList.add(new Person("Anni", 8200, "female", "New York"));
personList.add(new Person("Owen", 9500, "male", "New York"));
personList.add(new Person("Alisa", 7900, "female", "New York"));
// 将员工按薪资是否高于8000分组
Map<Boolean, List<Person>> part = personList.stream().collect(Collectors.partitioningBy(x -> x.getSalary() > 8000));
// 将员工按性别分组
Map<String, List<Person>> group = personList.stream().collect(Collectors.groupingBy(Person::getSex));
// 将员工先按性别分组,再按地区分组
Map<String, Map<String, List<Person>>> group2 = personList.stream().collect(Collectors.groupingBy(Person::getSex, Collectors.groupingBy(Person::getArea)));
System.out.println("员工按薪资是否大于8000分组情况:" + part);
System.out.println("员工按性别分组情况:" + group);
System.out.println("员工按性别、地区:" + group2);
}
}
接合(joining)
joining可以将stream中的元素用特定的连接符(没有的话,则直接连接)连接成一个字符串。
public class StreamTest {
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
String names = personList.stream().map(p -> p.getName()).collect(Collectors.joining(","));
System.out.println("所有员工的姓名:" + names);
List<String> list = Arrays.asList("A", "B", "C");
String string = list.stream().collect(Collectors.joining("-"));
System.out.println("拼接后的字符串:" + string);
}
}
规约(reducing)
Collectors类提供的reducing方法,相比于stream本身的reduce方法,增加了对自定义归约的支持。
public class StreamTest {
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Tom", 8900, 23, "male", "New York"));
personList.add(new Person("Jack", 7000, 25, "male", "Washington"));
personList.add(new Person("Lily", 7800, 21, "female", "Washington"));
// 每个员工减去起征点后的薪资之和(这个例子并不严谨,但一时没想到好的例子)
Integer sum = personList.stream().collect(Collectors.reducing(0, Person::getSalary, (i, j) -> (i + j - 5000)));
System.out.println("员工扣税薪资总和:" + sum);
// stream的reduce
Optional<Integer> sum2 = personList.stream().map(Person::getSalary).reduce(Integer::sum);
System.out.println("员工薪资总和:" + sum2.get());
}
}
排序(sorted)
sorted,中间操作。
sorted():自然排序,流中元素需实现Comparable接口
sorted(Comparator com):Comparator排序器自定义排序
案例:将员工按工资由高到低(工资一样则按年龄由大到小)排序
public class StreamTest {
public static void main(String[] args) {
List<Person> personList = new ArrayList<Person>();
personList.add(new Person("Sherry", 9000, 24, "female", "New York"));
personList.add(new Person("Tom", 8900, 22, "male", "Washington"));
personList.add(new Person("Jack", 9000, 25, "male", "Washington"));
personList.add(new Person("Lily", 8800, 26, "male", "New York"));
personList.add(new Person("Alisa", 9000, 26, "female", "New York"));
// 按工资升序排序(自然排序)
List<String> newList = personList.stream().sorted(Comparator.comparing(Person::getSalary)).map(Person::getName)
.collect(Collectors.toList());
// 按工资倒序排序
List<String> newList2 = personList.stream().sorted(Comparator.comparing(Person::getSalary).reversed())
.map(Person::getName).collect(Collectors.toList());
// 先按工资再按年龄升序排序
List<String> newList3 = personList.stream()
.sorted(Comparator.comparing(Person::getSalary).thenComparing(Person::getAge)).map(Person::getName)
.collect(Collectors.toList());
// 先按工资再按年龄自定义排序(降序)
List<String> newList4 = personList.stream().sorted((p1, p2) -> {
if (p1.getSalary() == p2.getSalary()) {
return p2.getAge() - p1.getAge();
} else {
return p2.getSalary() - p1.getSalary();
}
}).map(Person::getName).collect(Collectors.toList());
System.out.println("按工资升序排序:" + newList);
System.out.println("按工资降序排序:" + newList2);
System.out.println("先按工资再按年龄升序排序:" + newList3);
System.out.println("先按工资再按年龄自定义降序排序:" + newList4);
}
}
List<String> regionList = Arrays.asList("全省", "福州", "厦门", "泉州", "莆田", "漳州", "龙岩", "三明", "南平", "宁德", "平潭");
List<TestObject> valueList = new ArrayList<>();
valueList.add(new TestObject("福州", "111"));
valueList.add(new TestObject("泉州", "111"));
valueList.add(new TestObject("漳州", "111"));
valueList.add(new TestObject("全省", "111"));
valueList.add(new TestObject("宁德", "111"));
valueList.add(new TestObject("三明", "111"));
valueList.sort(Comparator.comparingInt((TestObject o) -> regionList.indexOf(o.getAreaName())).reversed());
提取/组合
public class StreamTest {
public static void main(String[] args) {
String[] arr1 = { "a", "b", "c", "d" };
String[] arr2 = { "d", "e", "f", "g" };
Stream<String> stream1 = Stream.of(arr1);
Stream<String> stream2 = Stream.of(arr2);
// concat:合并两个流 distinct:去重
List<String> newList = Stream.concat(stream1, stream2).distinct().collect(Collectors.toList());
// limit:限制从流中获得前n个数据
List<Integer> collect = Stream.iterate(1, x -> x + 2).limit(10).collect(Collectors.toList());
// skip:跳过前n个数据
List<Integer> collect2 = Stream.iterate(1, x -> x + 2).skip(1).limit(5).collect(Collectors.toList());
System.out.println("流合并:" + newList);
System.out.println("limit:" + collect);
System.out.println("skip:" + collect2);
}
}
ReentrantLock
加锁是为了保证线程安全实现数据同步手段的一种。经常用到的两种同步方式是Synchronized和ReentrantLock。这两种方式都是阻塞式同步,就是说当一个线程获得了对象锁,进入了同步块,其他访问该同步块的线程都必须阻塞在同步块外面等待。
区别:这两种方式最大的区别就是Synchronized是java的关键字,是原生语法层面的互斥,需要jvm实现;而ReentrantLock是JDK1.5之后提供的API层面的互斥锁,需要lock()和unlock()方法配合try/finally语句来完成,ReentrantLock完全可以替代Synchronized,并且可以更灵活的使用锁机制。遇到异常时,synchronized如果不catch,锁会被自动释放,而ReentrantLock需要手动释放。
private static final ReentrantLock lock = new ReentrantLock();
/**
* 缓存首页数据 5min一次
*/
@Scheduled(cron = "0 */5 * * * ? ")
@PostConstruct
private void init() {
LOGGER.info("缓存首页数据开始");
List<OverhaulPlanContent> planList = overhaulPlanDao.getPlanBriefData(null);
// 临时map
Map<String, Map<String, Map<String, List<OverhaulPlanContent>>>> tempPlanBriefDataMap = new HashMap<>();
planList.forEach(o -> tempPlanBriefDataMap.computeIfAbsent(o.getStepName(), k -> new HashMap<>())
.computeIfAbsent(o.getItemType(), k -> new HashMap<>())
.computeIfAbsent(o.getDispatchGuanXia(), k -> new ArrayList<>())
.add(o));
lock.lock();
try {
// 给缓存数据重新赋值
planBriefDataMap.clear();
tempPlanBriefDataMap.forEach((k, v) -> {
planBriefDataMap.put(k, v);
});
} finally {
lock.unlock();
}
LOGGER.error("缓存首页数据结束");
}
具体区别
- 原始构成
Synchronized 是关键字,属于JVM层面,底层是通过 monitorenter 和 monitorexit 完成,依赖于 monitor 对象来完成。由于 wait/notify 方法也依赖于 monitor 对象,因此只有在同步块或方法中才能调用这些方法。
Lock 是 java.util.concurrent.locks.lock 包下的,是 api层面的锁。 - 使用方法
Synchronized 不需要用户手动释放锁,代码完成之后系统自动让线程释放锁
ReentrantLock 需要用户手动释放锁,没有手动释放可能导致死锁。 - 等待是否可以中断
Synchronized 不可中断,除非抛出异常或者正常运行完成
ReentrantLock 可以中断。一种是通过 tryLock(long timeout, TimeUnit unit),另一种是lockInterruptibly()放代码块中,调用interrupt()方法进行中断。 - 加锁是否公平
synchronized 是非公平锁
ReentrantLock 默认非公平锁,可以在构造方法传入 boolean 值,true 代表公平锁,false 代表非公平锁。 - 锁绑定多个 Condition
Synchronized 只有一个阻塞队列,只能随机唤醒一个线程或者唤醒全部线程。
ReentrantLock 用来实现分组唤醒,可以精确唤醒。
随机数函数
SecureRandom sr = new SecureRandom();
int num = sr.nextInt()
HTML
form
<label for="username">
<input type="text" id="username">用户名
</label>
加载默认图片
<div class="content_bar">
<div class="bar_icon">
<img src="/dataInteraction/img/graphIconOpacity/${item}.png"
onerror='this.src="/dataInteraction/img/graphIconOpacity/默认样式.png"'
width="84"
height="84">
</div>
<div class="bar_title">${item}</div>
</div>
CSS
Flex布局
display: flex;
display: inline-flex;
// 行内元素
align-items: center;
// 垂直居中
justify-content: center;
// 水平居中
flex-wrap: wrap;
// 可换行
flex-direction: row;justify-content: space-between;
// 两端对齐
flex-direction
flex-direction属性决定主轴的方向。
row
(默认值):主轴为水平方向,起点在左端。row-reverse
:主轴为水平方向,起点在右端。column
:主轴为垂直方向,起点在上沿。column-reverse
:主轴为垂直方向,起点在下沿。
flex-wrap
flex-wrap属性定义如果一条轴线排不下,如何换行。
nowrap
(默认值):不换行。wrap
:换行,第一行在上方。wrap-reverse
:换行,第一行在下方。
flex-flow
flex-flow属性是flex-direction属性和flex-wrap属性的简写形式,默认值为row nowrap
。
justify-content
justify-content属性定义了项目在主轴上的对齐方式。
flex-start
(默认值):左对齐flex-end
:右对齐center
: 居中space-between
:两端对齐,项目之间的间隔都相等。space-around
:每个项目两侧的间隔相等。所以,项目之间的间隔比项目与边框的间隔大一倍。
align-items
align-items属性定义项目在交叉轴上如何对齐。
flex-start
:交叉轴的起点对齐。flex-end
:交叉轴的终点对齐。center
:交叉轴的中点对齐。baseline
: 项目的第一行文字的基线对齐。stretch
(默认值):如果项目未设置高度或设为auto,将占满整个容器的高度。
前端
移动端和PC端样式自适应
<meta name="viewport" content="width=device-width, initial-scale=1.0">
格式化数据
/**
* 将数字取整为10的倍数
* @param {Number} num 需要取整的值
* @param {Boolean} ceil 是否向上取整
* @param {Number} prec 需要用0占位的数量
*/
const formatInt = (num, prec = 2, ceil = true) => {
const len = String(num).length;
if (len <= prec) { return num };
const mult = Math.pow(10, prec);
return ceil ?
Math.ceil(num / mult) * mult :
Math.floor(num / mult) * mult;
}
// formatInt(2345, 2, true) -> 2400
// formatInt(2345, 2. false) -> 2300
// formatInt(2345, 3, true) -> 3000
// formatInt(2345, 3, false) -> 2000
获取元素
const test = document.getElementById("test")
const parent = test.parentNode; // 找父节点
const chils = test.childNodes; // 找所有子节点
const first = test.firstChild; // 找第一个子节点
const last = test.lastChild; // 找最后一个子节点
const previous = test.previousSibling; // 上一个兄弟节点
const next = test.nextSibling; // 下一个兄弟节点
$(`#id`).parent(); // 找父元素
$(`#id`).parents(); // 找所有祖先元素
$(`#id`).children(); // 找所有子元素
$(`#id`).prev(); // 找上一个兄弟节点
$(`#id`).prevAll(); // 查询所有之前的兄弟节点
$(`#id`).next(); // 找下一个兄弟节点
$(`#id`).nextAll(); // 查找所有之后的兄弟节点
$(`#id`).siblings(); // 查找所有兄弟节点不分前后
$(`#id`).find(); // 查找指定节点
$("ul li").eq(1); // 选择匹配的索引顺序为1的元素
$("ul li").first(); // 选择匹配的第一个元素
$("ul li").last(); // 选择匹配的最后一个元素
$("ul li").slice(1, 4) // 选择第2~4个元素
$("ul li").filter(":even") // 选择所有奇数顺序的元素
页面跳转
window.open()
window.history.go(-1)
window.history.back(); // 返回上一页并强行刷新
window.parent.location.replace()
localStorage
localStorage.getItem()
localStorage.setItem()
localStorage.removeItem()
on方法绑定事件
$("父选择器").on('事件名', '子选择器', function (e) {}
Promise
promise是一个构造函数,本身有all、reject、resolve几个眼熟的方法,原型上有then、catch等方法。
promise的构造函数接收一个参数,是函数,该函数需要传入两个参数:resolve和reject,分别表示异步操作执行成功后的回调函数和异步操作执行失败后的回调函数。
请求后台数据
getData(url, data) {
return new Promise((resolve, reject) => {
$.ajax({
url: url,
type: "post",
data: data,
success: (res) => {
if (res.code) {
resolve(res.data);
} else {
reject(res.msg);
}
},
error: (e) => {
reject(e);
}
});
})
},
utils.getData(url, {}).then((res) => {
}).catch(e => {
});
数组和JSON
数组转json JSON.stringify()
json转数组 JSON.parse()
数据遍历
遍历数组
data.forEach((item, idx, arr) => {})
$.each(arr,function(idx, item)) {}
for(let o of this.listData) {
if(o.id == obj.value) {
this.addAndEditForm = o;
break; // 使用let..of 可以中途终止循环
}
}
遍历集合
var newData = data.map(function (item, idx, arr) {
item.newAttr = newAttrValue;
return item;
});
返回一个新数组,新数组中的元素为原始数组元素调用函数处理后的值,并不会改变原数组。有返回值。
for (let key in data) {}
data[key]及key键对应键值
排序
按指定顺序排序
例:按指定省份顺序排序
res = res.sort((val1,val2)=>{
let order = ["甘肃","宁夏","青海","新疆","陕西"];
return order.indexOf(val1.name) - order.indexOf(val2.name);
})
按大小顺序排序
例:按时间顺序排序
res.sort((val1,val2)=>{
let value1 = moment(val1.name).toDate();
let value2 = moment(val2.name).toDate();
if(value1 === value2){
return 0;
}
return value1.getTime() > value2.getTime()?1:-1;
});
高阶函数
const nums = [10, 20, 111, 222]
let total = nums.filter(function(n) {
return n < 100
}).map(function(n) {
return n * 2
}).reduce(function(prevValue, n) {
return prevValue + n
}, 0)
let total2 =
nums.filter(n => n < 100)
.map(n => n * 2)
.reduce((pre, n) => pre + n, 0)
let total3 =
nums.filter(n => n < 100)
.map(n => n * 2)
.reduce((pre, n) => {pre + n}, 0)
reduce()
对数组中所有的值进行汇总
const app = new Vue({
el: '#app',
data: {
carts: [{
price: 85,
count: 1
},{
price: 59,
count: 1
},{
price: 139,
count: 1
},{
price: 128,
count: 1
}],
series: [
{data: [10]},
{data: [8]},
{data: [6]},
]
},
filters: {
formatPrice(price) {
return '¥' + price.toFixed(2)
}
},
methods: {
},
computed: {
totalPrice() {
// let result = 0;
// this.carts.forEach((item) => {
// result += item.price * item.count;
// })
// return result;
// return result = this.carts.reduce((previousValue, currentValue) => {
// return previousValue + currentValue.price * currentValue.count
// }, 0)
// return result = this.carts.reduce((previousValue, currentValue) => previousValue + currentValue.price * currentValue.count, 0)
return this.series.map((item) => item.data[0]).reduce((previousValue, currentValue) => previousValue + currentValue, 0)
}
}
})
filter()
filter()中的回调函数有一个要求: 必须要返回一个boolean值
true: 当返回true时,函数内部会自动将这次回调的n加入新的数组中
false:当返回false时,函数内部会过滤掉这次的n
arr.filter()
array.filter((value, index, arr) => {value === '匹配对象'})
//1. 去掉空字符串、undefined、null
array.filter((value, index, arr) => {value})
//2. 数组去重
array.filter((value, index, arr) => {arr.indexOf(value) === index})
map()
响应式的数组方法
push() 在数据最后添加元素
pop() 删除数组的最后一个元素
shift() 删除数组的第一个元素
unshift() 在数组最前面添加元素
splice( , ) 删除、插入、替换元素
删除元素:第1个元素对应操作位置,第2个元素传入要删除几个元素(如果不传则删除所有)
插入元素:第1个元素对应操作位置,第2个元素传入0,后面跟上要插入的元素
替换元素:第1个元素对应操作位置,第2个元素传入要替换几个元素,后面用于替换前面的元素
sort() 排序
reverse() 反转
对时间操作 moment.js
localStorage
this.tableData = this.tableData.concat(res);
localStorage.setItem("alarm", JSON.stringify(this.tableData));
// 获取历史数据
let alarmHistory = JSON.parse(localStorage.getItem("alarm")); // 历史告警数据
this.tableData = alarmHistory;
if (alarmHistory != null) {
this.maxId = Math.max.apply(Math,alarmHistory.map(item => { return item.id }))
}
if (this.maxId && this.maxId != '-Infinity') {
this.getNewInformation();
} else {
this.getInformationListTable()
}
对url中的参数进行简单编解码
进行页面跳转时 有时候需要通过拼接url的方式传参,参数中可能包含“?=&”之类的字符,这时需要对url携带的参数进行编码和解码。
前端使用encodeURIComponent编码,使用decodeURIComponent解码。
后端使用URLEncoder.encode编码,使用URLDecoder.decode解码。
LayUI
表单
layui.use('form', () => {
layui.form.render('select'); // 表单重置下拉框
layui.form.on('select(dbSrc)', (data) => { // 监听下拉框值变化
console.log(data.value)
});
})
$("#formId")[0].reset() // 表单内容重置
Element UI
表单
element-ui 移除整个表单的校验结果(或重置表单及验证) 使用方法
本例子表单为dialog形式出现,dialogFormVisible为父组件传来的控制表单显示的值,
通过watch监视,如果显示,调用表单重置方法resetvalidate();
子组件结构中有ref属性为’userAdd’
export default{
methods:{
resetvalidate(formName){
if(this.$refs[formName]!==undefined){
this.$refs[formName].resetFields();//如果只是清除表单验证用 this.$refs[formName].clearValidate();
}
},
},
watch: {
dialogFormVisible(val) {
this.myFormVisible = val;
if(val){
this.resetvalidate('userAdd')
}
},
myFormVisible(val){
this.$emit('addsubmit',val)
}
},
props:['dialogFormVisible']
}
Vue
v-cloak
[v-cloak] {
display: none;
}
[Vue warn]: Failed to resolve directive: modle (found in )单词拼错。
nextTick
this.$nextTick(() => {
});
v-on修饰符
@click.stop
阻止冒泡
@click.prevent
阻止默认方法调用
@keyup.enter
监听某个键帽的点击
v-model.修饰符
v-model.lazy
失去焦点或回车时才更新
v-model.number
typeof age 为number类型 不是String
v-model.trim
去掉空格
@click
// 不传参数,但方法有形参 默认传$event
@click = "test"
methods: {
test(event) {
console.log(event.target.value)
}
}