JDK安装
;1;编写接口
public interface Animal {
void run();
void eat();
/**
* 接口的默认方法
*/
default void sleep(){
System.out.println(;睡觉;);
}
/**
* 静态方法
*/
static void st(){
System.out.println(;静态方法;);
}
}
;2;编写实现类
public class Dog implements Animal{
;Override
public void run() {
System.out.println(;小狗跑;);
}
;Override
public void eat() {
System.out.println(;小狗吃;);
}
public static void main(String[] args) {
Dog dog = new Dog();
dog.run();
dog.eat();
//直接能掉接口的默认实现
dog.sleep();
//直接调用静态方法
Animal.st();
}
}
;3;运行结果
Base64是网络上常见的用于传输8Bit字节码的编码方式之一;Base64就是一种基于64个可打印字符来表示二进制数据的方法;基于64个字符A-Z、0-9、a-z、;、/的编码方式;是一种能将任意二级制数据用64种字节组合成字符串的方法;而这个二进制数据和字符串资料之间是可以相互转换的;实际应用上;Base64不但可以将二进制数据可视化;还可以用于数据传输的加密
;1;编码实战
public static void main(String[] args) {
//目标字符串
String str = ;lixiang;;
//加密
BASE64Encoder encoder = new BASE64Encoder();
String strEncode = encoder.encode(str.getBytes(;UTF-8;));
System.out.print(;加密后;;;strEncode);
//解密
BASE64Decoder decoder = new BASE64Decoder();
String strDecode = new String(decoder.decodeBuffer(strEncode),;UTF-8;);
System.out.print(;解密后;;;strDecode);
}
;2;运行结果
;1;编码实战
public static void main(String[] args) {
//目标字符串
String str = ;lixiang;;
//加密
Base64.Encoder encoder = Base64.getEncoder();
String strEncode = encoder.encodeToString(str);
System.out.print(;加密后;;;strEncode);
//解密
Base64.Decoder decoder = Base64.getDecoder();
String strDecoder = new String(decoder.decode(strEncode),;UTF-8;);
System.out.print(;解密后;;;strDecoder);
}
;2;运行结果
LocalDate:不包含具体时间的日期
LocalTime:不包含日期的时间
LocalDateTime:包含了日期及时间
LocalDate today = LocalDate.now();
获取当前日期的年份;today.getYear()
获取当前日期的月份;today.getMonth()
获取当前日期的月份;数字;;today.getMonthValue()
获取当前日期是当月的多少号;today.getDayOfMonth()
获取当前日期是这一周的周几;today.getDayOfWeek();
获取当前日期;1年,必须返回新的对象才会;1;today.plusYears(1)
获取当前日期;1月,必须返回新的对象才会;1;today.plusMonths(1)
获取当前日期;1周,必须返回新的对象才会;1;today.plusWeeks(1)
获取当前日期;1天,必须返回新的对象才会;1;today.plusDays(1)
获取当前日期-1天,必须返回新的对象才会-1;today.minusDays(1)
获取当前日期-1周,必须返回新的对象才会-1;today.minusWeeks(1)
获取当前日期-1年,必须返回新的对象才会-1;today.minusYears(1)
获取当前日期-1月,必须返回新的对象才会-1;today.minusMonths(1)
日期比较;当前日期与目标日期之后;date.isAfter(today)
日期比较;当前日期与目标日期之前;date.isBefore(today)
修改当前日期的年份;today.withYear(1999)
修改当前日期的月份;today.withMonth(3)
修改当前对象在当月的日期;today.withDayOfMonth(5)
比较两个日期是否相等;date.isEqual(today)
//获取当前时间
LocalDateTime today = LocalDateTime.now();
System.out.println(;today:;;today);
//日期格式化
LocalDateTime today = LocalDateTime.now();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern(;yyyy-MM-dd HH:mm:ss;);
String date = dtf.format(today);
//定制日期对象,参数分别对应;年、月、日、时、分、秒
LocalDateTime localDateTime = LocalDateTime.of(2021,11,12,8,10,2);
LocalDateTime date1 = LocalDateTime.of(2021,11,12,8,10,2);
LocalDateTime date2 = LocalDateTime.of(2020,11,12,8,10,2);
Duration duration = Duration.between(date1,date2);
//两个时间差的天数
System.out.println(duration.toDays());
//两个时间的小时差
System.out.println(duration.toHours());
//两个时间的分钟差
System.out.println(duration.toMinutes());
//两个时间的毫秒差
System.out.println(duration.toMillis());
//两个时间的纳秒差
System.out.println(duration.toNanos());
;1;Optional类的用处
主要解决的问题是空指针异常;NullPointerException;
;2;创建Optional类
;3;访问Optional对象的值
Student student = null;
//Optional<Student> optional = Optional.of(student);
Optional<Student> optional = Optional.ofNullable(student);
//拿值之前先判断optional是否为空
if(optional.isPresent()){
Student student1 = optional.get();
}else{
System.out.println(;optional中值为空;);
}
;4;兜底orElse方法
Student student1 = null;
Student student2 = new Student(;李祥;,20);
//当student1为空时;就返回student2对象;不为空就返回student1对象
Student orElse = Optional.ofNullable(student1).orElse(student2);
System.out.println(orElse);
//判断对象年龄如果为空值就传送一个默认7
Optional.ofNullable(student1).map(obj->obj.getAge()).orElse(7);
System.out.println(;age:;;integer);
;1;什么是Lambda表达式
;2;JDk8之前创建线程的方式与Lambda创建线程的方式
public static void main(String[] args) {
new Thread(new Runable(){
;Override
public void run(){
System.out.print(;测试;);
}
}).start();
}
public static void main(String[] args) {
//new Thread(()->{System.out.print(;测试;);}).start();
new Thread(()->System.out.print(;测试;)).start();
}
;3;集合容器元素排序
public static void main(String[] args) {
Arrays.asList(;aaa;,;bbb;,;ccc;,;fff;,;ddd;);
Collections.sort(list,new Comparator<String>(){
;Override
public int compare(String a,String b){
return a.compareTo(b);
}
});
}
public static void main(String[] args) {
Arrays.asList(;aaa;,;bbb;,;ccc;,;fff;,;ddd;);
Collections.sort(list,(x,y) -> x.comparaTo(y));
}
;4;Lambda表达式的使用场景
一个接口中只包含一个需要实现的方法;可以使用Lambda表达式;这样的接口称为函数式接口;语法;(params) -> expression
(x,y) -> {System.out.print(x;y);}
(x,y):这一部分为参数;当只有一个参数时可以省略括号;x->,当没有参数时;直接写括号()
->:表示指向执行的方法体
{System.out.print(x;y);}:表示执行的方法体;可以是表法式;也可以是代码块;当是表达式的时候可以省略{};没有{}时;不要写;代码块时要加上{};就和平常的语句逻辑一样。
好处;Lambda表达式的实现方式时在本质以匿名内部类的方式进行实现;减少代码冗余;提高开发效率。
;5;自定义Lambda接口
定义一个函数接口;需要加上;FuncationInterface注解;只允许有一个默认的方法实现。
定义一个可以使用加减乘除的接口;之前需要定义四个方法;现在只需一个方法
编写接口;定义方法;加上FunctionInterface注解
;FunctionInterface
public interface OperFunction<R,T>{
R operator(T t1,T t2);
}
public static Integer operator(Integer x,Integer y,OperFunction<Integer,Integer> of){
return of.operator(x,y);
}
public static void main(String[] args) {
System.out.print(operator(x,y,(x,y)->x;y));
System.out.print(operator(x,y,(x,y)->x-y));
System.out.print(operator(x,y,(x,y)->x*y));
System.out.print(operator(x,y,(x,y)->x/y));
}
Consumer<T>;消费型接口;有入参;无返回值。
void accept(T t);
Supplier<T>;供给型接口;无入参;有返回值。
T get();
Function<T,R>;函数型接口;有入参;无返回值
R apply(T t);
Predicate<T>;断言型接口;有入参;有返回值;返回值类型确定是boolean
boolean test(T t);
;FunctionalInterface
public interface Function<T, R> {
/**
* Applies this function to the given argument.
* ;param t the function argument
* ;return the function result
*/
R apply(T t);
}
public class FunctionObj implements Function {
;Override
public Object apply(Object o) {
return o;;;apply处理;;
}
}
public static void main(String[] args) {
Object lixiang = apply(;lixiang;, new FunctionObj());
System.out.println(lixiang);
}
public static Object apply(String o,FunctionObj obj){
return obj.apply(o);
}
;FunctionalInterface
public interface BiFunction<T,U,R>{
R apply(T t,U u);
}
public static void main(String[] args) {
System.out.println(operator(10,21,(a,b)->a;b));
System.out.println(operator(10,2,(a,b)->a-b));
System.out.println(operator(8,4,(a,b)->a*b));
System.out.println(operator(10,2,(a,b)->a/b));
}
public static Integer operator(Integer a, Integer b, BiFunction<Integer,Integer, Integer> bf) {
return bf.apply(a, b);
}
;FunctionalInterface
public interface Consumer<T> {
void accept(T t);
}
public static void main(String[] args) {
sendMessage(;11111111;,phone -> System.out.println(phone;;已经被发送;));
}
public static void sendMessage(String phone, Consumer<String> consumer){
consumer.accept(phone);
}
;FunctionalInterface
public interface Supplier<T> {
T get();
}
public static void main(String[] args) {
Student student = newStudent();
System.out.println(student);
}
public static Student newStudent(){
Supplier<Student> supplier=()-> new Student(;lixiang;,20);
return supplier.get();
}
;FunctionalInterface
public interface Predicate<T> {
boolean test(T t);
}
public static void main(String[] args) {
List<String> list = Arrays.asList(;awewrwe;,;vdssdsd;,;aoooo;,;psdddsd;);
List<String> results = filter(list, obj -> obj.startsWith(;a;));
System.out.println(results);
}
public static List<String> filter(List<String> list,Predicate<String> predicate){
List<String> results = new ArrayList<>();
for (String s : list) {
if(predicate.test(s)){
results.add(s);
}
}
return results;
}
方法引用是一种更简洁易懂的lambda表达式;操作符是双冒号::,用来直接访问类或者实例已经存在的方法或者构造方法。
通过语法引用;可以将方法的引用赋值给一个变量
语法;左边是容器;可以是类名;实例名;;中间是;::;;右边是相应的方法名
静态方法;ClassName::methodName
实例方法;Instance::methodName
构造函数;类名::new
单个参数
Function<入参1;返回类型> func = 方法引用
应用 func.apply(݇入参);
两个参数
BiFunction<݇入参1, 入参2> func = 方法引用
应用 func.apply(入参1;入参2);
测试调用
public static void main(String[] args) {
//静态方法的调用
Function<String,Integer> function1 = Integer::parseInt;
Integer num = function1.apply(;1024;);
System.out.println(;转化后;;;num);
//实例方法的调用
String context = ;lixiang;;
Function<Integer,String> function2 = context::substring;
String str = function2.apply(1);
System.out.println(;截取后的字符串;;;str);
//构造方法的调用,双参数
BiFunction<String,Integer,Student> function3 = Student::new;
Student lixiang = function3.apply(;lixiang;, 20);
System.out.println(lixiang);
//构造方法的调用;单个参数
Function<String,Student> function4 = Student::new;
Student lisi = function4.apply(;lisi;);
System.out.println(lisi);
//函数作为参数传递到另一个方法中
String sayHello = sayHello(String::toUpperCase, ;lixiang;);
System.out.println(sayHello);
}
public static String sayHello(Function<String,String> function,String str){
String apply = function.apply(str);
return apply;
}
;1;什么是stream
Stream中文称为;流;;通过将集合转化为这么一种叫做流的元素队列;通过声明性方式;能够对集合中的每一个元素进行一些列并行或穿行的流水线操作。
元素是特定类型的对象;所以元素集合看作一种流;流在管道中传输;且可以在管道的节点上进行处理;比如 排序;聚合;过滤等
;2;案例
List<String> list = Arrays.asList(;SpringBoot;, ;SpringCloud;, ;redis;, ;RabbitMQ;);
List<String> collect = list.stream().map(obj -> obj ; ;-拼接;).collect(Collectors.toList());
for (String s : collect) {
System.out.println(s);
}
;1;map函数
将流中的每一个元素T映射成R;类似类型转换;
应用场景;转换对象;类似DO对象转换成DTO对象
map函数源码
public static void main(String[] args) {
List<User> users = Arrays.asList(
new User(1, ;小东;, ;123;),
new User(2, ;小李;, ;123;),
new User(3, ;小王;, ;123;),
new User(4, ;小张;, ;123;));
List<UserDTO> collect = users.stream().map(user -> {
UserDTO userDTO = new UserDTO();
userDTO.setUserId(user.getId());
userDTO.setUsername(user.getName());
return userDTO;
}).collect(Collectors.toList());
for (UserDTO userDTO : collect) {
System.out.println(userDTO);
}
}
;2;filter函数
用于通过设置的条件过滤出元素
应用场景;过滤出符合条件的元素
filter函数源码
List<String> list = Arrays.asList(;SpringBoot;, ;SpringCloud;, ;Redis;, ;RabbitMQ;,;JUC;);
//filter
List<String> collect5 = list.stream().filter(str -> str.length() > 4).collect(Collectors.toList());
System.out.println(collect5);
;1;sorted函数
//排序;sort();默认升序
List<String> collect1 = list.stream().sorted().collect(Collectors.toList());
System.out.println(;sort()按照英文字母升序;;;collect1);
//根据长度排序;默认升序
List<String> collect2 = list.stream().sorted(Comparator.comparing(obj -> obj.length())).collect(Collectors.toList());
System.out.println(;sort()按照英文字母的长度升序;;;collect2);
//根据长度排序,降序
List<String> collect3 = list.stream().sorted(Comparator.comparing(obj -> obj.length(),Comparator.reverseOrder())).collect(Collectors.toList());
System.out.println(;sort()按照英文字母的长度降序;;;collect3);
;2;limit函数
//根据长度排序,降序,截取前三个
List<String> collect4 = list.stream()
.sorted(Comparator.comparing(String::length,Comparator.reverseOrder())).limit(3)
.collect(Collectors.toList());
System.out.println(collect4);
;1;allMatch函数
List<String> list = Arrays.asList(;SpringBoot;, ;SpringCloud;, ;Redis;, ;RabbitMQ;,;Netty;,;JUC;,;docker;);
boolean allFlag = list.stream().allMatch(str -> str.length()>5);
System.out.println(;allFlag全部满足返回true:;;allFlag);
;2;anyMatch函数
List<String> list = Arrays.asList(;SpringBoot;, ;SpringCloud;, ;Redis;, ;RabbitMQ;,;Netty;,;JUC;,;Docker;);
boolean allFlag = list.stream().anyMatch(str -> str.length()>5);
System.out.println(;allFlag全部满足返回true:;;allFlag);
;1;max函数
Optional<Student> max = list.stream().max(Comparator.comparingInt(Student::getAge));
if (max.isPresent()){
System.out.println(;最大年龄;;;max.get().getAge());
}
;2;min函数
Optional<Student> min = list.stream().min((student1, student2) -> {
return Integer.compare(student1.getAge(), student2.getAge());
});
if(min.isPresent()){
System.out.println(;最小年龄;;;min.get().getAge());
}
List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
//串行流
System.out.print(;串行流;;);
numbers.stream().forEach(num -> System.out.print(num;; ;));
System.out.println();
//并行流
System.out.print(;并行流;;);
numbers.parallelStream().forEach(num -> System.out.print(num;; ;));
for (int i = 0; i < 10; i;;) {
//List<Integer> list = new ArrayList<>();
CopyOnWriteArrayList list = new CopyOnWriteArrayList();
IntStream.range(1,100).parallel().forEach(list::add);
System.out.println(list.size());
}
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
//将集合内的元素相加
Integer integer = list.stream().reduce((x, y) -> x ; y).get();
System.out.println(;集合内元素相加;;;integer);
//初始值100;将集合内的元素相加
Integer integer1 = list.stream().reduce(100,(x,y) -> x;y);
System.out.println(;100累加集合内的元素;;;integer1);
//判断最大值返回
Integer integer2 = list.stream().reduce((x, y) -> x > y ? x : y).get();
System.out.println(;集合内最大元素;;;integer2);
List<Student> result = Arrays.asList(new Student(32),new Student(33),new Student(21),new Student(29),new Student(18));
result.forEach(obj -> System.out.println(obj.getAge()));
//重载方法一
<R> R collect(Supplier<R> supplier, BiConsumer<R, ? super T> accumulator, BiConsumer<R, R>combiner);
//重载方法二
<R, A> R collect(Collector<? super T, A, R> collector)
public static <T> Collector<T, ?, List<T>> toList() {
return new CollectorImpl<>(
(Supplier<List<T>>) ArrayList::new,
List::add,
(left, right) -> {
left.addAll(right);
return left; },
CH_ID
);
}
常见的收集器
//三种重载方法
Collectors.joining() //无参数默认按照空字符拼接
Collectors.joining(;-;) //一个参数;按照“-”进行分割
Collectors.joining(;-;,;{;,;};) //三个参数;第一个为分隔符;后两个为前缀后缀
List<String> list = Arrays.asList(;SpringBoot;,;Docker;,;Java;,;SpringCloud;,;Netty;);
String collect1 = list.stream().collect(Collectors.joining());
System.out.println(collect1);
String collect2 = list.stream().collect(Collectors.joining(;-;));
System.out.println(collect2);
String collect3 = list.stream().collect(Collectors.joining(;-;, ;{;, ;};));
System.out.println(collect3);
Collectors.partitioningBy()会根据筛选条件进行分组;返回一个Map<Boolean,List>类型;boolean为true的表示符合条件的;false的为不符合筛选条件的。
源码
List<String> list = Arrays.asList(;Java;,;SpringBoot;,;HTML5;,;CSS3;);
Map<Boolean, List<String>> collect = list.stream().collect(Collectors.partitioningBy(obj -> obj.length() > 4));
System.out.println(collect);
List<Student> students = Arrays.asList(
new Student(;lx;, 23, ;北京;),
new Student(;ls;, 24, ;天津;),
new Student(;zs;, 23, ;⼴东;),
new Student(;ww;, 22, ;⼴东;),
new Student(;ld;, 20, ;北京;),
new Student(;xs;, 20, ;⼴东;),
new Student(;ok;, 25, ;北京;));
Map<String, List<Student>> collect = students.stream().collect(Collectors.groupingBy(obj -> obj.getProvince()));
//第二种方式
//Map<String, List<Student>> collect1 = students.stream().collect(Collectors.groupingBy(Student::getProvince));
collect.forEach((key,value) -> {
System.out.println(;----;;key);
value.forEach(obj-> System.out.println(obj));
});
List<Student> students = Arrays.asList(
new Student(;lx;, 23, ;北京;),
new Student(;ls;, 24, ;天津;),
new Student(;zs;, 23, ;⼴东;),
new Student(;ww;, 22, ;⼴东;),
new Student(;ld;, 20, ;北京;),
new Student(;xs;, 20, ;⼴东;),
new Student(;ok;, 25, ;北京;));
Map<String, Long> collect1 = students.stream().collect(Collectors.groupingBy(Student::getProvince, Collectors.counting()));
collect1.forEach((key,value) -> {
System.out.println(;---;;key);
System.out.println(;---;;value);
});
IntSummaryStatistics collect = students.stream().collect(Collectors.summarizingInt(Student::getAge));
System.out.println(;平均值;;;collect.getAverage());
System.out.println(;总人数;;;collect.getCount());
System.out.println(;年龄总和;;;collect.getSum());
System.out.println(;最大值;;;collect.getMax());
System.out.println(;最小值;;;collect.getMin());
;1;需求;求两个集合的交集、差集、去重并集;两集合的各自平均值;总和
;2;创建两个集合
//总价 35
List<VideoOrder> videoOrders1 = Arrays.asList( new VideoOrder(;20190242812;, ;springboot教程;, 3), new VideoOrder(;20194350812;, ;微服务SpringCloud;, 5), new VideoOrder(;20190814232;, ;Redis教程;, 9), new VideoOrder(;20190523812;, ;⽹⻚开发教程;, 9), new VideoOrder(;201932324;, ;百万并发实战Netty;, 9));
//总价 54
List<VideoOrder> videoOrders2 = Arrays.asList( new VideoOrder(;2019024285312;, ;springboot教程;, 3), new VideoOrder(;2019081453232;, ;Redis教程;, 9), new VideoOrder(;20190522338312;, ;⽹⻚开发教程;, 9), new VideoOrder(;2019435230812;, ;Jmeter压⼒测试;, 5), new VideoOrder(;2019323542411;, ;Git;Jenkins持续集成;, 7), new VideoOrder(;2019323542424;, ;Idea全套教程;, 21));
;3;注意一点要重写equals和hashcode方法
;Override
public boolean equals(Object o) {
if(o instanceof VideoOrder){
VideoOrder o1 = (VideoOrder)o;
return this.title.equals(o1.title);
}
return super.equals(o);
}
;Override
public int hashCode() {
return title.hashCode();
}
;4;计算两个集合的交集
List<VideoOrder> clist = videoOrder1.stream().filter(videoOrder2::contains).collect(Collectors.toList());
;5;计算两个集合的差集
List<VideoOrder> nclist = videoOrder1.stream().filter(obj -> !videoOrder2.contains(obj)).collect(Collectors.toList());
;6;计算两个集合的去重并集
List<VideoOrder> allList = videoOrder1.paralleStream().distinct().collect(Collectors.toList());
allList.addAll(videoOrder2);
;7;计算订单价格的平均值
double avg = videoOrder1.stream().collect(Collectors.averagingInt(VideoOrder::getMoney)).doubleValue();
;8;计算订单价格的总和
Integer sum = videoOrders1.stream().collect(Collectors.summingInt(VideoOrder::getMoney));
public static void main(String[] args) throws FileNotFoundException {
String filePath = ;F:1.txt;;
test(filePath);
}
private static void test(String filePath) throws FileNotFoundException {
OutputStream outputStream = new FileOutputStream(filePath);
try {
outputStream.write((filePath;;学习;).getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws FileNotFoundException {
String filePath = ;F:1.txt;;
test(filePath);
}
private static void test(String filePath) throws FileNotFoundException {
//自动关流;当有多个文件时;直接用;分割就可以
try (OutputStream outputStream = new FileOutputStream(filePath)){
outputStream.write((filePath ; ;学习;).getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) throws FileNotFoundException {
String filePath = ;F:1.txt;;
test(filePath);
}
private static void test(String filePath) throws FileNotFoundException {
OutputStream outputStream = new FileOutputStream(filePath);
try {
outputStream.write((filePath;;学习;).getBytes());
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws FileNotFoundException {
String filePath = ;F:1.txt;;
test(filePath);
}
private static void test(String filePath) throws FileNotFoundException {
//自动关流;当有多个文件时;直接用;分割就可以
try (OutputStream outputStream = new FileOutputStream(filePath)){
outputStream.write((filePath ; ;学习;).getBytes());
} catch (IOException e) {
e.printStackTrace();
}
}