aLambda_01InnerClassDemo
package com.se.aLambda;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class _01InnerClassDemo {
public static void main(String[] args) {
List<Person> ps = new ArrayList<>();
ps.add(new Person("张三", 19));
ps.add(new Person("李四", 20));
ps.add(new Person("micheal", 18));
ps.add(new Person("tom", 19));
// Collections.sort(ps);
// System.out.println(ps);
//按照年龄降序排序
// Comparator c = new Comparator<Person>() {
// @Override
// public int compare(Person o1, Person o2) {
// return o2.getAge() - o1.getAge();
// }
// };
Collections.sort(ps, (o1, o2) -> o2.getAge() - o1.getAge());
System.out.println(ps);
}
}
//类一旦定义完,不要轻易修改源代码
class Person implements Comparable<Person> {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Person o) {
return age - o.age;
}
}
aLambda_02LambdaDemo
package com.se.aLambda;
/**
* Lambda 表达式的应用:
* 1. Lambda表达式实际上就是匿名内部类的简化版本
* 2. Lambda表达式是jdk1.8引入的一个重要的特性,另一个是集合的流式编程
* 3. Lambda表达式是java为了扩展函数式编程引用的
* 4. Lambda表达式可以理解为是一个匿名函数(匿名方法:方法名没名字)
* 5. Lambda表达式只能作用于函数式接口(有且只有一个抽象方法的接口)
*/
public class _02LambdaDemo {
public static void main(String[] args) {
//2. 测试实现类
NoParameterNoReturn class1 = new class1();
class1.print();
//3. 使用匿名内部类的方式,实现NoParameterNoReturn接口打印“java.ez”
NoParameterNoReturn nono = new NoParameterNoReturn() {
@Override
public void print() {
System.out.println("哈哈哈,我哭了");
}
};
nono.print();
//4. 使用Lambda表达式,实现NoParameterNoReturn接口打印“java.ez”
NoParameterNoReturn n1 = () -> System.out.println("java.ez");
n1.print();
//5. 使用Lambda表达式,实现OneParameterNoReturn接口打印“我喜欢”+参数,传入苹果
OneParameterNoReturn oneNoReturn = info -> System.out.println("我喜欢" + info);
oneNoReturn.print("苹果");
//6. 使用lambda表达式,实现MuilParameterNoReturn接口,打印两个参数拼接的效果,测试传入"我今年""18"
MuilParameterNoReturn muilNoReturn = (info, age) -> System.out.println(info + age);
muilNoReturn.print("我今年", 18);
//7. 使用lambda表达式,实现NoParameterReturn接口,计算两个随机数,区间[25,40]的和","
NoParameterReturn noParameterReturn1 = () ->
(int) (Math.random() * 16 + 25)
+ ((int) (Math.random() * 16 + 25));
System.out.println(noParameterReturn1.calculate());
//8. 使用lambda表达式,实现0neParameterReturn接口,计算形参的立方,测试传入3
OneParameterReturn oneR2 = a -> a * a * a;
System.out.println(oneR2.calculate(3));
//9. 使用lambda表达式,实现MuilParameterReturn接口,计算两个形参的立方和,测试传入3和4
MuilParameterReturn mR1 = (int a, int b) -> a * a * a + b * b * b;
System.out.println(mR1.calculate(3, 4));
}
}
//1. 使用实现类的方法,实现NoParameterNoReturn接口
class class1 implements NoParameterNoReturn {
@Override
public void print() {
System.out.println("java.ez");
}
}
//里面的抽象方法,没有形参,也没用返回值
interface NoParameterNoReturn {
void print();
}
//一个形参,没有返回值
interface OneParameterNoReturn {
void print(String info);
}
//多个形参,无返回值
interface MuilParameterNoReturn {
void print(String info, int age);
}
//没有形参,有返回值
@FunctionalInterface //注解是用来校验是否是函数式接口
interface NoParameterReturn {
int calculate();
}
//一个形参,有返回值
interface OneParameterReturn {
int calculate(int a);
}
//多个形参,有返回值
interface MuilParameterReturn {
int calculate(int a, int b);
}
aLambda_03LambdaDemo02
package com.se.aLambda;
import java.util.*;
/**
* 第一个:排序时,使用比较器的时候
* 第二个:迭代时
* 第三个:根据条件删除元素
*/
public class _03LambdaDemo02_InList {
public static void main(String[] args) {
//测试第一种
List<String> list = new ArrayList<>();
list.add("michael");
list.add("david");
list.add("bob");
list.add("lucy");
//按照字符串的长度降序: 比较器使用lambda表达的方法
Collections.sort(list, (a,b)->b.length()-a.length());
System.out.println(list);
//测试第二种: 集合的迭代
Integer[] arr = new Integer[]{4,5,10,7,2};
List<Integer> nums = Arrays.asList(arr);
/*
forEach(Consumer c)的源码:
for(T t : this){
c.accept(t);
}
Consumer是一个函数式接口:里面的抽象方法
void accept(T t);
因此只需要向forEach()方法中传入 accept的匿名函数,也就是lambda表达式即可
*/
nums.forEach((num-> System.out.println(num)));
//继续简化
nums.forEach(System.out::println);
//Set类型的迭代
Set<Integer> set = new HashSet<>(nums);
System.out.println(set);
set.forEach(System.out::println);
//Map的迭代
Map<String,Integer> map = new HashMap<>();
map.put("张三", 18);
map.put("李四", 19);
map.put("王五", 17);
map.put("赵六", 28);
//Key的迭代
map.keySet().forEach(key-> System.out.println(key));
//entrySet的迭代
map.entrySet().forEach(entry-> System.out.println(entry.getKey()+" "+entry.getValue()));
//value的迭代
map.values().forEach(value-> System.out.println(value));
//测试第三种:根据条件删除元素
List<Integer> ages = Arrays.asList(18,19,17,20,17);
List<Integer> ages2 = new ArrayList<>(ages);
/*
removeIf(Predicate filter(过滤器)): 满足条件就会删除
源码解析:
内部逻辑就是一个迭代器遍历集合,根据条件做删除操作
条件就是filter的test方法
Predicate是一个函数式接口,里面有boolean test(T t)方法
因此我们在使用时就是写一个lambda表达式来实现test方法即可
*/
ages2.removeIf(age->age.equals(17));
System.out.println(ages2);
}
}
bVariableCatch_01InnerClassDemo
package com.se.bVariableCatch;
/**
* 变量的捕获: 在内部对外部的变量的引用和访问
* 1. 实例变量(成员变量,属性,全局变量)
* 2. 静态变量
* 3. 本地形参
* 4. 本地变量(局部变量)
*
* 总结:
* 1. 匿名内部类访问的变量,只能访问不能覆盖
* 2. Lambda表达式,也可以访问上述四种变量,依然是对局部变量只能访问,不能覆盖。
*/
public class _01InnerClassDemo {
private int a; //实例变量
private static int b; //静态变量
static {
b = 2;
}
public _01InnerClassDemo(){
a = 1;
}
public void m1(int c){
int d = 4;
MyTest mt = new MyTest() {
@Override
public void test1() {
//访问外部类的成员变量:外部类名.this.成员变量 或者直接写
System.out.println("instance variable:"+ a);
//访问外部类的静态变量:外部类名.静态变量 或者直接写
System.out.println("static variable:"+ b);
//匿名内部类访问的方法形参,也只能访问,不能覆盖。
System.out.println("method parameter:"+ c);
//匿名内部类访问的局部变量是默认被final修饰的,final修饰的变量只能初始化一次,不能被第二次赋值
System.out.println("local variable:"+ d);
// c = 10; d = 5;
}
};
//调用test1方法
mt.test1();
}
public void m2(int c){
int d = 4;
MyTest mt = () -> {
//访问外部类的成员变量:外部类名.this.成员变量 或者直接写
System.out.println("instance variable:"+ a);
//访问外部类的静态变量:外部类名.静态变量 或者直接写
System.out.println("static variable:"+ b);
//访问的方法形参,也只能访问,不能覆盖。
System.out.println("method parameter:"+ c);
//访问的局部变量是默认被final修饰的,final修饰的变量只能初始化一次,不能被第二次赋值
System.out.println("local variable:"+ d);
};
mt.test1();
}
public static void main(String[] args){
//测试:创建外部类对象,调用m1方法
_01InnerClassDemo c1 = new _01InnerClassDemo();
// c1.m1(3);
c1.m2(3);
}
}
interface MyTest{
void test1();
}
cStream_01DataSourceGet
package com.se.cStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
/**
* 集合的流式编程:
* 1. 传统方式,如果对集合中的元素做处理时,可能要书写大量代码,比如增删过滤等
* 2. 集合的流式编程,是JDK1.8引入的两个重要特征之一
* 3. 集合的流式编程是对传统方式的一种简化操作
* 4. 集合的流式编程分三步:
* -第一步:获取数据源(关联数据源),返回Stream对象
* -第二步:对Stream对象进行各种处理,处理后结果依旧是Stream对象
* -第三步:对Stream对象的最后整合处理,处理后的结果,一般情况下不再是Stream对象
* 可能是一个具体的数字,字符串或者一个新的集合。
*
* tips:整个过程中,数据源本身不会发生变化
*/
public class _01DataSourceGet {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
nums.add(5);
/*
如果想要对这个集合进行流式处理,必须先获得数据源
*/
// 1. 获取的流对象,是串行的,不是并行的
Stream<Integer> stream = nums.stream();
// 2. 对流对象进行各种处理,返回新的流对象
Stream<Integer> stream1 = nums.parallelStream();
}
}
cStream_02Final_collect
package com.se.cStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* 集合流式编程的最终操作:
* 1. 将流中的的数据整合到一起,可以存入一个新的集合,也可以遍历或者统计
* 2. 最终操作,会关闭这个流。流中的数据都会被销毁。 关闭流之后继续操作流会报错
*
* 最终操作常用方法如下:
* 1. collect: 搜集方法可以将流的数据搜集成一个新的集合
* 该方法的形参是Collector接口(非函数式接口),可以用了知制定搜索规则
* 通常情况下,不需要程序员自己实现,Collectors工具类里提供的方法够用
*/
public class _02Final_collect {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
nums.add(5);
//获取数据源
Stream<Integer> Stream = nums.stream();
//搜集1 凑集为List集合
List<Integer> c1 = Stream.collect(Collectors.toList());
System.out.println(c1 == nums);
//搜集2 凑集为Set集合
Set<Integer> c2 = Stream.collect(Collectors.toSet());
System.out.println(c2 == nums);
/*
搜集3 搜集成Map集合
Collectors.toMap(keyMapper, valueMapper)
KeyMapper是函数式接口,里面只有一个R apply(T t) 抽象方法,我们就是通过lambda表达式来重写apply方法
valueMapper亦如此
*/
Map<String, Integer> c3 = Stream.collect(Collectors.toMap((e) -> "key" + e, e -> e));
System.out.println(c3);
}
}
cStream_03Final_reduce
package com.se.cStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Stream;
public class _03Final_reduce {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
nums.add(5);
Stream<Integer> stream = nums.stream();
/*
计算数据源的元素之核 方法参数也是lambda表达式 对应的抽象方法 R apply(T t ,U u);
返回的类型:Optional,需要调用官的get方法,获取里面的数据
Optional<Integer> reduce = stream.reduce((a, b) -> (a + b)); //15
*/
//a变量接受的是数据源中的第一个元素,然后b变量接受的是剩下的元素 a与b的关系是:a -= b
Optional<Integer> reduce = stream.reduce((a, b) -> (a - b)); //-13
int result = reduce.get();
System.out.println("计算结果:" + result);
}
}
cStream_04Final_count
package com.se.cStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class _04Final_count {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
nums.add(5);
Stream<Integer> stream = nums.stream();
/*
count是用于统计数据源的元素个数
底层源码: return mapToLong(e -> 1L).sum();
即将元素映射成1,然后求和。
*/
long count = stream.count();
System.out.println(count);
}
}
cStream_05Final_forEach_max_min
package com.se.cStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class _05Final_forEach_max_min {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
nums.add(5);
Stream<Integer> stream = nums.stream();
//forEach方法,对流中的数据进行遍历,遍历完毕,流就关闭了
stream.forEach(num -> System.out.println(num));
stream.forEach(System.out::println);
// max方法,返回流中最后的元素
int max = stream.max((a, b) -> a - b).get();
System.out.println(max);
// min方法,返回流中最前的元素
int min = stream.min((a, b) -> a - b).get();
System.out.println(min);
}
}
cStream_06Final_Matching
package com.se.cStream;
import java.util.ArrayList;
import java.util.List;
/**
* AllMatch: 当数据源中的所有元素都满足匹配条件,才返回true
* AnyMatch: 当数据源中的任意一个元素满足匹配条件,则返回true
* NoneMatch: 当数据源中的所有元素都不满足匹配条件,才返回true
*/
public class _06Final_Matching {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
nums.add(5);
boolean b = nums.stream().allMatch(e -> e < 10);
System.out.println(b);
boolean b1 = nums.stream().anyMatch(e -> e > 2);
System.out.println(b1);
boolean b2 = nums.stream().noneMatch(e -> e > 10);
System.out.println(b2);
}
}
cStream_07Final_find
package com.se.cStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
/**
* FindFirst:
* FindAny:
*
* 上述两个方法,针对于串行的流,获取的都是第一个元素
* 针对于并行的流,获取的元素应该不同
*/
public class _07Final_find {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
nums.add(5);
Stream<Integer> stream = nums.stream();
//串行的流演示
int e1 = nums.stream().findFirst().get();
System.out.println(e1);
int e2 = nums.stream().findAny().get();
System.out.println(e2);
//并行的流演示
Integer e3 = nums.parallelStream().findFirst().get();
System.out.println(e3);
Integer e4 = nums.parallelStream().findAny().get();
System.out.println(e4);
}
}
dStreamMiddel_01Filter_Distinct
package com.se.dStreamMiddel;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
public class _01Filter_distinct {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
nums.add(5);
nums.add(2);
nums.add(4);
/**
* filter(...) 过滤出来满足条件的数据,
* 比如,想要所有的奇数
*/
List<Integer> c1 = nums.stream().filter(x -> x%2!=0).collect(Collectors.toList());
System.out.println(c1);
/**
* distinct() 去重 Lambda表达式 可以理解为一个没有名字的方法
*
* int a 给a赋值, 传递的是具体数据 或者变量
* forEach(....表达式..)
*/
nums.stream().distinct().forEach(Class1::m1);
}
}
class Class1{
public static<T> void m1(T t){
System.out.println(t);
}
}
dStreamMiddel_02Sorted_limit_skip
package com.se.dStreamMiddel;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class _02Sorted_limit_skip {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(3);
nums.add(2);
nums.add(5);
nums.add(4);
nums.add(1);
Stream<Integer> stream = nums.stream();
//sorted() 升序排序 sorted(Comparator c) 自定义比较规则
nums.stream().sorted((a, b) -> b - a).forEach(System.out::println);
//limit(long size) 截取 :表示截取流中的前size个元素
nums.stream().limit(2).sorted((a, b) -> a - b).forEach(System.out::println);
//skip(long size) 跳过 :表示跳过流中的前size个元素
nums.stream().filter(e -> e != 2).sorted().skip(2).forEach(System.out::println);
}
}
dStreamMiddel_03Map_mapToInt
package com.se.dStreamMiddel;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class _03Map_mapToInt {
public static void main(String[] args) {
List<Integer> nums = new ArrayList<>();
nums.add(1);
nums.add(2);
nums.add(3);
nums.add(4);
nums.add(5);
Stream<Integer> stream = nums.stream();
//map(...): 将元素映射成另外一种类型 例如将上述的元素映射成字符串类型
List<String> c1 = nums.stream().map(e -> "" + e).collect(Collectors.toList());
System.out.println(c1);
/*
mapToInt(...): 将元素映射成int类型
mapToLong(...): 将元素映射成long类型
mapToDouble(...): 将元素映射成double类型
*/
int sum = nums.stream().mapToInt(e -> 1).sum();
System.out.println(sum);
}
}
dStreamMiddel_04FlatMap
package com.se.dStreamMiddel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* flatMap: 扁平式映射。
* 一般针对的都是集合元素仍然是一个集合。
* 普通的集合[1,2,3,4,5]
* 集合元素是几个的: [[1,2,10],[1,3,4],[2,4,5]]
*
* 扁平式映射: 就是将元素是集合的这种特殊集合,转成普通的集合
* 如 [[1,2],[1,3,4],[2,4,5]] => [1,2,10,1,3,4,2,4,5]
*/
public class _04FlatMap {
public static void main(String[] args) {
//集合out的元素仍然是集合
List<List<Integer>> out = new ArrayList<>();
out.add(Arrays.asList(1,2,10));
out.add(Arrays.asList(1,3,4));
out.add(Arrays.asList(2,4,5));
//flatMap(.....) 传入一个lambda表达式 : e->e.stream() 压平了。
long count = out.stream().flatMap(e -> e.stream()).count();
System.out.println("集合元素是几个的: " + count);
double asDouble = out.stream().flatMap(e -> e.stream()).mapToInt(e -> e).average().getAsDouble();
System.out.println(asDouble);
}
}
exercise_Program
package com.se.exercise;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* 需求 : 一个集合中存储了了若干个Student对象 , 要求查询出以下结果 :
* 1. 所有及格的学生信息
* 2. 所有及格的学生姓名
* 3. 所有学生的平均成绩
* 4. 班级的前3名(按照成绩)
* 5. 班级的3-10名(按照成绩)
* 6. 所有不及格的学生平均成绩
* 7. 将及格的学生 , 按照成绩降序输出所有信息
* 8. 班级学生的总分
*/
public class Program {
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student("A", 90));
list.add(new Student("B", 80));
list.add(new Student("C", 70));
list.add(new Student("D", 60));
list.add(new Student("E", 50));
list.add(new Student("F", 40));
list.add(new Student("G", 30));
list.add(new Student("H", 20));
list.add(new Student("I", 10));
list.add(new Student("J", 0));
System.out.println("1. 所有及格的学生信息:");
list.stream().filter(x -> x.getScore()>=60).forEach(System.out::println);
System.out.println("2. 所有及格的学生姓名:");
list.stream().filter(x->x.getScore()>=60).map(x->x.getName()).forEach(System.out::println);
System.out.println("3. 所有学生的平均成绩:");
System.out.println(list.stream().collect(Collectors.averagingInt(Student::getScore)));
System.out.println("4. 班级的前3名(按照成绩):");
list.stream().sorted((a,b)->b.getScore()-a.getScore()).limit(3).forEach(System.out::println);
System.out.println("5. 班级的3-10名(按照成绩):");
list.stream().sorted((a,b)->b.getScore()-a.getScore()).skip(2).forEach(System.out::println);
System.out.println("6. 所有不及格的学生平均成绩:");
System.out.println(list.stream().filter(x->x.getScore()<=60).collect(Collectors.averagingInt(Student::getScore)));
System.out.println("7. 将及格的学生 , 按照成绩降序输出所有信息:");
list.stream().filter(x->x.getScore()>=60).sorted((a,b)->b.getScore()-a.getScore()).forEach(System.out::println);
System.out.println("8. 班级学生的总分:");
System.out.println(list.stream().collect(Collectors.summingInt(Student::getScore)));
}
}
exercise_Student
package com.se.exercise;
public class Student {
private String name;
private int score;
public String getName() {
return name;
}
public int getScore() {
return score;
}
public Student(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public String toString() {
return String.format("姓名 : %s, 成绩 : %d", name, score);
}
}