package com.java8.test;
public class Employee {
private int id;
private String name;
private int age;
private double salary;
private Status status;
public Employee() {
}
public Employee(String name) {
this.name = name;
}
public Employee(String name, int age) {
this.name = name;
this.age = age;
}
public Employee(int id, String name, int age, double salary) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
}
public Employee(int id, String name, int age, double salary, Status status) {
this.id = id;
this.name = name;
this.age = age;
this.salary = salary;
this.status = status;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
public String show() {
return "测试方法引用!";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + id;
result = prime * result + ((name == null) ? 0 : name.hashCode());
long temp;
temp = Double.doubleToLongBits(salary);
result = prime * result + (int) (temp ^ (temp >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (age != other.age)
return false;
if (id != other.id)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (Double.doubleToLongBits(salary) != Double.doubleToLongBits(other.salary))
return false;
return true;
}
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + ", status=" + status
+ "]";
}
public enum Status {
FREE, BUSY, VOCATION;
}
}
package com.java8.test;
//交易类
public class Transaction {
private Trader trader;
private int year;
private int value;
public Transaction() {
}
public Transaction(Trader trader, int year, int value) {
this.trader = trader;
this.year = year;
this.value = value;
}
public Trader getTrader() {
return trader;
}
public void setTrader(Trader trader) {
this.trader = trader;
}
public int getYear() {
return year;
}
public void setYear(int year) {
this.year = year;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
@Override
public String toString() {
return "Transaction [trader=" + trader + ", year=" + year + ", value="
+ value + "]";
}
}
package com.java8.test;
//交易员类
public class Trader {
private String name;
private String city;
public Trader() {
}
public Trader(String name, String city) {
this.name = name;
this.city = city;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
@Override
public String toString() {
return "Trader [name=" + name + ", city=" + city + "]";
}
}
package com.java8.test;
import java.util.*;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.java8.test.Employee.Status;
public class TestStream {
/**
* 引用自:
* https://www.bilibili.com/video/BV1ut411g7E9
* only focus on use
* base on abstraction
* 难点:
* flatmap
* 规约与收集
* reduce与collect
*
* 可参考地址;
* https://mkyong.com/tutorials/java-8-tutorials/
*/
/**
* 参考:https://blog.csdn.net/yilu_beiyu/article/details/122241784 对比进行思考
*/
public void test1() {
/**
* 创建stream
* 对比:https://blog.csdn.net/yilu_beiyu/article/details/122811729
* 流的构造函数和选择函数
*
* this is use
* Stream.of
* Stream.iterate
* Stream.generate
* List.stream
* Arrays.stream
*
*/
//1. Collection 提供了两个方法 stream() 与 parallelStream()
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流
//2. 通过 Arrays 中的 stream() 获取一个数组流
Integer[] nums = new Integer[10];
Stream<Integer> stream1 = Arrays.stream(nums);
//3. 通过 Stream 类中静态方法 of()
Stream<Integer> stream2 = Stream.of(1, 2, 3, 4, 5, 6);
//4. 创建无限流
//迭代
Stream<Integer> stream3 = Stream.iterate(0, (x) -> x + 2).limit(10);
stream3.forEach(System.out::println);
//生成
Stream<Double> stream4 = Stream.generate(Math::random).limit(2);
stream4.forEach(System.out::println);
}
/**
* 中间操作
* <p>
* 筛选与切片
* filter——接收 Lambda , 从流中排除某些元素。
* limit——截断流,使其元素不超过给定数量。
* skip(n) —— 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
* distinct——筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
* <p>
* 映射
* map——接收 Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
* flatMap——接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
* <p>
* 排序
* sorted()——自然排序
* sorted(Comparator com)——定制排序
*/
public void test2() {
List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
Stream<String> stream = strList.stream()
.map(String::toUpperCase);
stream.forEach(System.out::println);
//站在使用的角度上
//only focus on use
Stream<Stream<Character>> stream2 = strList.stream()
.map(TestStream::filterCharacter);
//*****模拟flatmap的操作*****
stream2.forEach((sm) -> {
sm.forEach(System.out::println);
});
System.out.println("---------------------------------------------");
//flatmap接收一个生成流的方法
//用于处理流里面有流
//对比:https://blog.csdn.net/yilu_beiyu/article/details/122811729
Stream<Character> stream3 = strList.stream()
.flatMap(TestStream::filterCharacter);
stream3.forEach(System.out::println);
}
//*****************
//对每个元素生成一个流
public static Stream<Character> filterCharacter(String str) {
List<Character> list = new ArrayList<>();
for (Character ch : str.toCharArray()) {
list.add(ch);
}
return list.stream();
}
/**
* 终止操作:
*
* 查找与匹配:
* allMatch
* anyMatch
* noneMatch
* findFirst
* findAny
* count
* max
* min
*
*
* 归约
* 类似于js里面的accumulate:https://blog.csdn.net/yilu_beiyu/article/details/122811729
* reduce(T identity, BinaryOperator)
* reduce(BinaryOperator) ——可以将流中元素反复结合起来,得到一个值。
*
*
* 收集
* collect——将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
* Collectors.toList
* Collectors.toSet
* Collectors.toCollection(提供者),收集到特殊的数据结构中
* Collectors.toConcurrentMap等
* 包括Collector不是s,的of等方法
* 最大、最小、总和等值
* 分组
* 多级分组:groupingBy(function, collector)
* 分区:partitioningBy
* summarizingDouble
* joining
*
*/
List<Employee> emps = Arrays.asList(
new Employee(102, "李四", 79, 6666.66, Status.BUSY),
new Employee(101, "张三", 18, 9999.99, Status.FREE)
);
public void test3(){
emps.stream()
.map(i -> i.getName())
.collect(Collectors.toCollection(HashSet::new));
}
public void test4(){
Optional<Double> max = emps.stream()
.map(Employee::getSalary)
.collect(Collectors.maxBy(Double::compare));
System.out.println(max.get());
Optional<Employee> op = emps.stream()
.collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));
System.out.println(op.get());
Double sum = emps.stream()
.collect(Collectors.summingDouble(Employee::getSalary));
System.out.println(sum);
Double avg = emps.stream()
.collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println(avg);
Long count = emps.stream()
.collect(Collectors.counting());
System.out.println(count);
System.out.println("--------------------------------------------");
DoubleSummaryStatistics dss = emps.stream()
.collect(Collectors.summarizingDouble(Employee::getSalary));
System.out.println(dss.getMax());
}
//分组
public void test5(){
Map<Status, List<Employee>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus));
// .collect(Collectors.groupingBy((i) -> i.getStatus()));
System.out.println(map);
}
//多级分组
public void test6(){
Map<Status, Map<String, List<Employee>>> map = emps.stream()
.collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
if(e.getAge() >= 60)
return "老年";
else if(e.getAge() >= 35)
return "中年";
else
return "成年";
})));
System.out.println(map);
}
//分区
public void test7(){
Map<Boolean, List<Employee>> map = emps.stream()
.collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));
System.out.println(map);
}
public void test8(){
/**
* 给定一个数字列表,返回每个数字的平方的列表
*/
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(5);
list.add(6);
final List<Integer> collect = list.stream().map(i -> i * i)
.collect(Collectors.toList());
System.out.println(collect);
/**
* 使用map和reduce计算一个list中元素的个数
*/
final Optional<Integer> reduce1 = list.stream()
.map(i -> 1)
.reduce(Integer::sum);
//或者是
final Optional<Integer> reduce2 = list.stream()
.map(i -> 1)
.reduce((i, j) -> i + j);
final Integer reduce = list.stream()
.reduce(0,
(sum, i) -> sum + i,
(i, j) -> i + j);
System.out.println(reduce);
}
}
package com.java8.test;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class TestTransaction {
static List<Transaction> transactions = null;
static {
Trader raoul = new Trader("Raoul", "Cambridge");
Trader mario = new Trader("Mario", "Milan");
Trader alan = new Trader("Alan", "Cambridge");
Trader brian = new Trader("Brian", "Cambridge");
transactions = Arrays.asList(
new Transaction(brian, 2011, 300),
new Transaction(raoul, 2012, 1000),
new Transaction(raoul, 2011, 400),
new Transaction(mario, 2012, 710),
new Transaction(mario, 2012, 700),
new Transaction(alan, 2012, 950)
);
}
public static void main(String[] args) {
List<String> l = new ArrayList(Arrays.asList("one", "two"));
Stream<String> sl = l.stream();
l.add("three");
String s = sl.collect(Collectors.joining(" "));
System.out.println(s);
String concatenated = l.stream().reduce("", String::concat);
System.out.println(concatenated);
final ArrayList<Object> collect = l.stream().collect(() -> new ArrayList<>(),
(coll, n) -> coll.add(n.toUpperCase()),
(a, b) -> a.addAll(b));
System.out.println(collect);
//1. 找出2011年发生的所有交易, 并按交易额排序(从低到高)
//2. 交易员都在哪些不同的城市工作过?
//3. 查找所有来自剑桥的交易员,并按姓名排序
//4. 返回所有交易员的姓名字符串,按字母顺序排序
//5. 有没有交易员是在米兰工作的?
//6. 打印生活在剑桥的交易员的所有交易额
//7. 所有交易中,最高的交易额是多少
//8. 找到交易额最小的交易
transactions.stream()
.filter(i -> i.getYear() == 2011)
.sorted((a, b) -> a.getValue() - b.getValue())
.forEach(System.out::println);
transactions.stream()
.map(i -> i.getTrader().getCity())
// .collect(Collectors.toSet());
.distinct()
.forEach(System.out::println);
//这个不对,题目要的是交易员,而不是交易
transactions.stream()
.filter(i -> i.getTrader().getCity().equals("Cambridge"))
.sorted(Comparator.comparing(i -> i.getTrader().getName())) //(x, y) => f(x, y)可以简化为f
.forEach(System.out::println);
transactions.stream()
.filter(i -> i.getTrader().getCity().equals("Cambridge"))
.map(i -> i.getTrader())
.sorted(Comparator.comparing(Trader::getName))
// .sorted((i, j) -> i.getName().compareTo(j.getName()))
.forEach(System.out::println);
System.out.println("===========");
new TestTransaction().test3();
//4. 返回所有交易员的姓名字符串,按字母顺序排序
/**
* 重点:
* java中lambda表达式,重点是类中的方法,而不是类
* 比如:Stream<T> sorted(Comparator<? super T> comparator);
* 重点是Comparator中的方法int compare(T o1, T o2);而不是Comparator这个类
* sort中,你需要传入的是:int compare(T o1, T o2)这个方法
* 而纯函数式编程,比如js中就不存在这个问题,因为直接就是方法,没有类
*
* sort中传入的compare方法,compare方法是比较两个元素
*/
transactions.stream()
.map(i -> i.getTrader().getName())
.sorted(Comparator.comparing(i->i)) //keyExtractor i->i是一个key提取器
.forEach(System.out::println);
// .sorted(String::compareTo)
// .sorted((i, j) -> i.compareTo(j));
transactions.stream()
.map((t) -> t.getTrader().getName())
.flatMap(TestTransaction::filterCharacter)
.sorted((s1, s2) -> s1.compareToIgnoreCase(s2))
.forEach(System.out::print);
System.out.println();
List<Integer> li = new ArrayList<>();
li.add(1);
li.add(2);
li.add(3);
li.add(10);
li.stream()
.flatMap(TestTransaction::createStream)
.forEach(System.out::print);
System.out.println();
//5. 有没有交易员是在米兰工作的?
// transactions.stream()
// .map(i -> i.getTrader())
// .filter(i -> i.getCity().equals("Milan"))
// .forEach(System.out::println);
final boolean b = transactions.stream()
.anyMatch(i -> i.getTrader().getCity().equals("Milan"));
System.out.println(b);
//6. 打印生活在剑桥的交易员的所有交易额
final Integer cambridge = transactions.stream()
.filter(i -> i.getTrader().getCity().equals("Cambridge"))
.map(i -> i.getValue())
.reduce(0, Integer::sum);
System.out.println(cambridge);
// transactions.stream()
// .filter(i -> i.getTrader().getCity().equals("Cambridge"))
// .reduce(new Transaction(), (i, j) -> i.getValue()+j.getValue())
//7. 所有交易中,最高的交易额是多少
final Optional<Integer> max = transactions.stream()
.map(i -> i.getValue())
.max(Integer::compareTo);
//8. 找到交易额最小的交易
final Optional<Transaction> min = transactions.stream()
// .min((i, j) -> i.getValue() - j.getValue());
.min(Comparator.comparingInt(Transaction::getValue));
}
//1. 找出2011年发生的所有交易, 并按交易额排序(从低到高)
public void test1(){
transactions.stream()
.filter((t) -> t.getYear() == 2011)
.sorted((t1, t2) -> Integer.compare(t1.getValue(), t2.getValue()))
.forEach(System.out::println);
}
//2. 交易员都在哪些不同的城市工作过?
public void test2(){
transactions.stream()
.map((t) -> t.getTrader().getCity())
.distinct()
.forEach(System.out::println);
}
//3. 查找所有来自剑桥的交易员,并按姓名排序
public void test3(){
transactions.stream()
.filter((t) -> t.getTrader().getCity().equals("Cambridge"))
.map(Transaction::getTrader)
.sorted((t1, t2) -> t1.getName().compareTo(t2.getName()))
.distinct()
.forEach(System.out::println);
}
//4. 返回所有交易员的姓名字符串,按字母顺序排序
public void test4(){
transactions.stream()
.map((t) -> t.getTrader().getName())
.sorted()
.forEach(System.out::println);
System.out.println("-----------------------------------");
String str = transactions.stream()
.map((t) -> t.getTrader().getName())
.sorted()
.reduce("", String::concat);
System.out.println(str);
System.out.println("------------------------------------");
transactions.stream()
.map((t) -> t.getTrader().getName())
.flatMap(TestTransaction::filterCharacter)
.sorted((s1, s2) -> s1.compareToIgnoreCase(s2))
.forEach(System.out::print);
}
public static Stream<String> filterCharacter(String str){
List<String> list = new ArrayList<>();
for (Character ch : str.toCharArray()) {
list.add(ch.toString());
}
return list.stream();
}
//创建一个生成流的方法
public static Stream<Integer> createStream(int num) {
// final IntStream range = IntStream.range(0, num);
List<Integer> l = new ArrayList<>();
for (int i = 0; i <= num; i++){
l.add(i);
}
return l.stream();
}
//5. 有没有交易员是在米兰工作的?
public void test5(){
boolean bl = transactions.stream()
.anyMatch((t) -> t.getTrader().getCity().equals("Milan"));
System.out.println(bl);
}
//6. 打印生活在剑桥的交易员的所有交易额
public void test6(){
Optional<Integer> sum = transactions.stream()
.filter((e) -> e.getTrader().getCity().equals("Cambridge"))
.map(Transaction::getValue)
.reduce(Integer::sum);
System.out.println(sum.get());
}
//7. 所有交易中,最高的交易额是多少
public void test7(){
Optional<Integer> max = transactions.stream()
.map((t) -> t.getValue())
.max(Integer::compare);
System.out.println(max.get());
}
//8. 找到交易额最小的交易
public void test8(){
Optional<Transaction> op = transactions.stream()
.min((t1, t2) -> Integer.compare(t1.getValue(), t2.getValue()));
System.out.println(op.get());
}
}