Java8新特性 Stream() 数据操作
定义了一个实体类,Apple.java
public class Apple {
private Integer id;
private String name;
private Double money;
private Integer num;
/**状态: 1: 正常 2: 非正常**/
private String status;
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
public Apple(Integer id, String name, Double money, Integer num, String status) {
this.id = id;
this.name = name;
this.money = money;
this.num = num;
this.status = status;
}
@Override
public String toString() {
return "Apple{" +
"id=" + id +
", name='" + name + '\'' +
", money=" + money +
", num=" + num +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
}
Java新特性操作部分
import java.util.*;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import static java.util.Comparator.comparingLong;
import static java.util.stream.Collectors.collectingAndThen;
import static java.util.stream.Collectors.toCollection;
/**
*
* @author 王立朝
* @date 2020-8-30
* @description:
*/
public class Java8Test {
/**
* 使用java7进行排序
*
* @param names
*/
public void sortUsingJava7(List<String> names) {
Collections.sort(names, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});
for (String s : names) {
System.out.println("java7排序后的结果为: " + s);
}
}
/**
* 使用java8进行排序
*
* @param names
*/
public void sortUsingJava8(List<String> names) {
Collections.sort(names, (s1, s2) -> s1.compareTo(s2));
System.out.println("java 8 的语法");
for (String s : names) {
System.out.println("java7排序后的结果为: " + s);
}
}
/**
* 测试java7 和 java 8 的 排序
*/
public void testJava7And8Sort() {
List<String> nameList = new ArrayList<>();
nameList.add("Java");
nameList.add("Phyton");
nameList.add("JavaScript");
nameList.add("VUE");
nameList.add("BootStrap");
System.out.println("遍历之前的数据顺序为: ");
Java8Test java8Test1 = new Java8Test();
nameList.forEach(e -> System.out.println(e));
java8Test1.sortUsingJava7(nameList);
java8Test1.sortUsingJava8(nameList);
}
/**
* java 1.8 创建对象
*
* @param supplier
* @return
*/
public static Java8Test create(final Supplier<Java8Test> supplier) {
return supplier.get();
}
/**
* java8 对数据的处理
*/
public ArrayList<Apple> getData() {
ArrayList<Apple> apples = new ArrayList<>();
Apple apple1 = new Apple(1, "苹果1", 1.2, 10, "true");
Apple apple12 = new Apple(1, "苹果2", 1.1, 20, "false");
Apple apple2 = new Apple(2, "香蕉", 6.2, 5, "falseMe");
Apple apple4 = new Apple(4, "香蕉", 2.2, 10, "true");
Apple apple3 = new Apple(3, "荔枝", 0.5, 5, "false");
apples.add(apple1);
apples.add(apple12);
apples.add(apple2);
apples.add(apple3);
apples.add(apple4);
return apples;
}
/**
* 根据ID 进行分组,ID 相同的放到一起
*
* @param apples
*/
public void groupById(ArrayList<Apple> apples) {
// List以ID 分组,然后放到Map 中
Map<Integer, List<Apple>> groupby = apples.stream().collect(Collectors.groupingBy(Apple::getId));
System.out.println(groupby);
}
/**
* list 转换为Map,
* 注意: Collectors.toMap() 方法中,如果key有重复,会报错Duplicate key
* apple1,apple12的id都为1。可以用 (k1,k2)->k1 来设置,如果有重复的key,则保留key1,舍弃key2
*
* @param apples
*/
public void listToMap(ArrayList<Apple> apples) {
Map map = apples.stream().collect(Collectors.toMap(Apple::getId, a -> a, (k1, k2) -> k1));
for (Object key : map.keySet()) {
System.out.println("key= " + key + " and value= " + map.get(key));
}
}
/**
* 对数据进行过滤
*
* @param apples
*/
public void filterData(ArrayList<Apple> apples) {
List<Apple> list = apples.stream().filter(a -> a.getName().equals("香蕉")).collect(Collectors.toList());
Apple apple = null;
for (int i = 0; i < list.size(); i++) {
apple = list.get(i);
System.out.println("过滤香蕉的数据为: " + apple);
}
}
/**
* 按照某一个属性进行求和
*
* @param apples
*/
public void getSumByProperty(ArrayList<Apple> apples) {
int sum = apples.stream().mapToInt(Apple::getId).sum();
System.out.println("统计的结果为: " + sum);
}
/**
* 计算流中的最大值和最小值
* TODO 暂时还不确定这个方法到底是怎么用
*/
public void getMaxAndMinVal() {
/*Optional maxDish = Dish.menu.stream().
collect(Collectors.maxBy(Comparator.comparing(Dish::getCalories)));
maxDish.ifPresent(System.out::println);
Optional minDish = Dish.menu.stream().
collect(Collectors.minBy(Comparator.comparing(Dish::getCalories)));
minDish.ifPresent(System.out::println);*/
}
/**
* 对数据进行去重
*
* @param apples
*/
public void distinic(ArrayList<Apple> apples) {
// 根据id去重
List unique = apples.stream().collect(
collectingAndThen(
toCollection(() -> new TreeSet<>(comparingLong(Apple::getId))), ArrayList::new)
);
System.out.println("去重前数据遍历结果为: ");
apples.forEach(s -> {
System.out.println("去重前遍历的结果为: " + s);
});
System.out.println("去重后数据遍历结果");
unique.forEach(s -> {
System.out.println("去重后遍历的结果为: " + s);
});
}
/**
* TODO: 对数据进行操作
* TODO: 查找与匹配数据
* TODO: 1、检查是否匹配所有元素 allMatch
* TODO: 2、检查是否至少匹配一个元素 anyMatch
* TODO: 3、检查是否没有匹配的元素 noneMatch
* TODO: 4、返回第一个元素 findFirst
* TODO: 5、返回当前流中的任意一个元素 findAny
* TODO: 6、返回流中元素的总个数 count
* TODO: 7、返回流中的最大值 max
* TODO: 8、返回流中的最小值 min
**/
public void testStreamApi(ArrayList<Apple> apples) {
// 判断 列表里面的值是否都是true allMatch
boolean aTrue = apples.stream().allMatch((e) -> e.getStatus().equals("true"));
System.out.println("判断 列表里面的值是否都是true-->" + aTrue);
boolean anyMatch = apples.stream().anyMatch((e) -> e.getStatus().equals("false"));
System.out.println("判断列表里面的值是否至少匹配一个元素->" + anyMatch);
boolean noneMatch = apples.stream().noneMatch((e) -> e.getStatus().equals("false"));
System.out.println("判断列表里面的值是否一个都没有匹配到->" + noneMatch);
Optional<Apple> first = apples.stream().sorted(Comparator.comparing(Apple::getMoney)).findFirst();
System.out.println("获取列表中的第一个元素(先根据 money进行排序,然后)->" + first);
Optional<Apple> findAny = apples.stream().filter((e) -> e.getStatus().equals("false")).findAny();
System.out.println("获取列表中任意一个元素->" + findAny);
long listCount = apples.stream().count();
System.out.println("获取列表的数量->" + listCount);
long falseCount = apples.stream().filter((e) -> e.getStatus().equals("false")).count();
System.out.println("查询列表中 状态是false 的总共有几个 ->" + falseCount);
Optional<Double> max = apples.stream().map(Apple::getMoney).max(Double::compareTo);
System.out.println("查询money最大的 ->" + max);
Optional<Apple> min = apples.stream().sorted(Comparator.comparingDouble(Apple::getMoney))
.min(Comparator.comparingInt(Apple::getNum));
System.out.println("查询 num 最小的值-> " + min);
}
public static void main(String[] args) {
// 使用java8 来创建一个对象
Java8Test java8Test = Java8Test.create(Java8Test::new);
java8Test.testJava7And8Sort();
// 使用java8 对数据进行处理
// 1.对数据进行分组
java8Test.groupById(java8Test.getData());
// 2.对list 类型的数据转换为Map类型
java8Test.listToMap(java8Test.getData());
// 3.读数据进行过滤
java8Test.filterData(java8Test.getData());
// 4、对数据按照某一个属性进行求和
java8Test.getSumByProperty(java8Test.getData());
//5、对数据去重
java8Test.distinic(java8Test.getData());
// 6、检查list集合中status的值是否都是true
java8Test.testStreamApi(java8Test.getData());
}
}
1、需求背景
有一个list中存放了若干个BeanA,想针对这个list进行遍历,取里面的BeanA中的几个字段,放到新的BeanB中,重新输出成新的list;
2、代码思路(使用lambda)
按照原来的写法,使用for循环遍历整个list,取出每个BeanA的字段set到BeanB中,然后把BeanB对象add到新的list中,遍历结束,新的list也就add结束;
按照lambda写法,需要使用.stream
、.map
、.collect
输出新的集合;
3、代码明细
//BeanA中字段:id,name,age,phone //BeanB中字段:id,name,age //e为BeanA对象 //BeanB对象需要有全参数的构造方法,这样才能方便的将e中取出的值直接set到BeanB对象中处理 List<BeanA> newList = oldList.stream() .map(e -> new BeanB(e.getId(), e.getName(), e.getAge())) .collect(Collectors.toList());
--------------------------------------------------------分割线-----------------------------------------------------
需求: 根据多个字段对一个List集合对象进行分组,并统计每组的数量
实现:
import lombok.Data; import lombok.experimental.Accessors; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.stream.Collectors; /** * @author 王立朝 * @date 2023/7/16 * @description: */ public class Test { public static void main(String[] args) { List<Score> scoreList = new ArrayList<>(); scoreList.add(new Score().setStudentId("001").setScoreYear("2018").setScore(100.0)); scoreList.add(new Score().setStudentId("001").setScoreYear("2019").setScore(59.5)); scoreList.add(new Score().setStudentId("001").setScoreYear("2019").setScore(59.5)); scoreList.add(new Score().setStudentId("001").setScoreYear("2019").setScore(59.5)); scoreList.add(new Score().setStudentId("001").setScoreYear("2018").setScore(59.5)); scoreList.add(new Score().setStudentId("001").setScoreYear("2019").setScore(99.0)); scoreList.add(new Score().setStudentId("002").setScoreYear("2018").setScore(99.6)); //根据scoreYear字段进行分组 Map<String, Long> map = scoreList.stream().collect( Collectors.groupingBy( score -> score.getScoreYear() + score.getStudentId(),Collectors.counting() )); System.out.println("map = " + map); map.forEach((k,v)->{ System.out.println("k->" + k +" " + "v->" + v); }); } @Data @Accessors(chain = true) static class Score{ private String studentId; private String scoreYear; private Double score; } }
结果为:
map = {2018001=2, 2018002=1, 2019001=4} k->2018001 v->2 k->2018002 v->1 k->2019001 v->4
需求: 定义了一个Map, 一个List ,需要把List中在map中匹配到的值过滤出来,并得到map的映射
实现方式如下:
public class MyStreamTest { public static void main(String[] args) { Map<Integer,String> map = new HashMap<>(); map.put(1,"a"); map.put(2,"b"); map.put(3,"c"); map.put(4,"d"); map.put(5,"e"); List<String> list = new ArrayList<>(); list.add("1"); list.add("2"); list.add("3"); list.add("4"); list.add("5"); list.add("6"); list.add("7"); list.add("8"); List<String> collect = list.stream().map(Integer::parseInt) .filter(map::containsKey).map(map::get).collect(Collectors.toList()); System.out.println("collect = " + collect); } }
结果为:
collect = [a, b, c, d, e]
阳光总在风雨后!