Stream优化代码,瞬间干净了
前言
Java8的新特性主要是Lambda表达式和流,当使用Lambda和流一起来优化代码时,真的让人感觉瞬间清醒了。
一、流(Stream)简化代码
现在有一个需求,需要对数据库查询的商品进行一个数据处理,方便前端数据展示:
1.筛选出库存小于等于10的商品
2.对筛选出的商品进行价格排序
3.获取排序后的商品的名称
public class Goods {
/**
* 商品id
*/
private Integer goods_id;
/**
* 商品名称
*/
private String goods_name;
/**
* 商品价格
*/
private double goods_price;
/**
* 商品库存
*/
private Integer goods_inventory;
}
如果按照Java8以前的代码实现,肯定时先进行查询,然后foreach进行比较,然后进行排序,然后再只获取名称 放到list集合中返回,这样的话我们就进行了很多操作,最起码方法得写两三个。
但是使用stream可以让我们的代码非常简化,如下:
List<Goods> list = goodsService.findAllGoodsNoLimitPage();
List<String> name_list = list.stream()
//筛选出库存大于20的商品
.filter(goods -> goods.getGoods_inventory()<=10)
//对筛选出的商品进行价格排序
.sorted(Comparator.comparing(Goods::getGoods_price))
//获取排序后的商品的名字
.map(Goods::getGoods_name)
//转换成List集合
.collect(Collectors.toList());
一气呵成,怎么样,是不是很简单。
我们还可以使用流将查询到的数据进行map集合排序存储,如下:
//根据价格排序返回一个map集合
Map<Double,List<Goods>> map = list.stream().collect(groupingBy(Goods::getGoods_price));
看到这里,是不是要大喊流 Stream Api 牛批,接下来我们再详细的看看流。
二、流Stream
1.什么是流
流是从支持数据处理操作的源生成的元素序列,源可以是数组、文件、集合、函数。流不是集合元素,它不是数据结构并不保存数据,它的主要目的在于计算。
2.如何生成流
流的生成方式有五种:
(1)通过集合生成
//通过集合生成流
List<String> stringList = Arrays.asList("a","b","c");
Stream<String> stream = stringList.stream();
(2)通过数组生成流
//通过数组生成流
int[] arr = new int[]{1,2,3};
IntStream stream = Arrays.stream(arr);
(3)通过值生成流
//通过值生成流
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
(4)通过文件生成
//通过文件生成
Stream<String> lines = Files.lines(Paths.get("data.txt"), Charset.defaultCharset())
(5)通过函数生成 提供了 iterate 和 generate 两个静态方法从函数中生成流
iterator
Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(5);
iterate 方法接受两个参数,第一个为初始化值,第二个为进行的函数操作,因为 iterator 生成的流为无限流,通过 limit 方法对流进行了截断,只生成 5 个偶数
generator
Stream<Double> stream = Stream.generate(Math::random).limit(5);
generate 方法接受一个参数,方法参数类型为 Supplier,由它为流提供值。generate 生成的流也是无限流,因此通过 limit 对流进行了截断