几个后面会用到的类
- 实体类Dish
public class Dish {
private Integer id;
private String name;
private boolean isVegetarian;
//省略get,set等
}
Filter
该操作会接受一个条件作为参数,并返回一个包含所有符合该条件的流.
- 实体Dish有个属性isVegetarian,筛选出所有素菜,并创建一张素食菜单,并输出
dishes.stream()
.filter(Dish::isVegetarian) //过滤掉所有非素菜的
.collect(toList()) //把过滤后的Dish转换为数组
.forEach(System.out::println); //输出
- distinct()方法,去掉重复的元素
筛选出列表中所有的偶数,并确保没有重复。
Stream.of(1, 2, 3, 4, 5, 7, 9, 5, 14, 1, 2, 3, 4, 6)
.filter(x -> x % 2 == 0)
.distinct() //去重
.forEach(System.out::println);
- limit限制查询多少个元素 ,skip为跳过多少元素 略过
Sorted 排序
- int数组排序(Integer1.8后多了一个compare方法可以用来排序,基础类型sorted里面不写也可以排)
numbers.stream()
.sorted(Integer::compare)
.collect(Collectors.toList())
.forEach(System.out::println);
- 根据Id来排序(两种方法)
dishes.stream()
.sorted((x, y) -> x.getId())
.collect(toList())
.forEach(System.out::println);
dishes.stream()
.sorted(Comparator.comparing(Dish::getId))
.collect(toList())
.forEach(System.out::println);
- 根据Id逆序排序 (reversed() 函数)
dishes.stream()
.sorted(Comparator.comparing(Dish::getId).reversed())
.collect(toList())
.forEach(System.out::println);
Map
- 取到所有菜的名称长度
dishes.stream()
.map(Dish::getName) //取到所有菜的名称
.map(String::length)//这边的map处理的是上一个map输出的值,因为上一个Map返回的是String,所有这边用String,其他类型同理,不一样会报错,
.forEach(System.out::println);
查找和匹配
查看数据集中的某些元素是否匹配一个给定的值。
Stream API通过 allMatch 、 anyMatch 、 noneMatch 、 findFirst 和 findAny 方法提供了这样的工具
- allMatch 所有值都匹配
- anyMatch 只要匹配到一个就可以
- noneMatch 没有匹配到
- findFirst 找到第一个值
- findAny 跟findFirst差不多,都是找到就返回
public void test4() {
boolean hasVegetarian = dishes.stream()
.anyMatch(Dish::isVegetarian);
System.out.println(hasVegetarian);
Optional<Dish> first = dishes.stream() //optional
.filter(dish -> !dish.isVegetarian())
.findFirst();
System.out.println(first);
}
Reduce
- Reduce求和
public void test5(){
//以前的写法
int sum = 0;
for (int x : numbers) {
sum += x;
}
System.out.println(sum);
//reduce写法
Integer reduce1 = numbers.stream().reduce(0, (a, b) -> a + b);
System.out.println(reduce1);
//Integer等方法已经有现成的sum方法
Integer reduce2 = numbers.stream().reduce(0, Integer::sum);
System.out.println(reduce2);
//无初始值------?
Optional<Integer> reduce3 = numbers.stream().reduce(Integer::sum);
System.out.println(reduce3);
}
- Reduce求最大值
public void test6(){
Optional<Integer> reduce = numbers.stream().reduce(Integer::max);
boolean present = reduce.isPresent();
if (present) {
System.out.println(reduce.get());
}
}
Optional类简单介绍
Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。
- 构建源码
正常构建
public static <T> Optional<T> of(T value) {
return new Optional<>(value);
}
空值构建
public static <T> Optional<T> ofNullable(T value) {
return value == null ? empty() : of(value);
}
- 常用方法 isPresent(),get()
Optional 类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
public boolean isPresent() {
return value != null;
}
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
- 上面的isPresent(),get()方法可以用ifPresent代替,后面是个Lamada表达式,当存在值时执行后面的方法
源码
public void ifPresent(Consumer<? super T> consumer) {
if (value != null)
consumer.accept(value);
}
例子:如果val存在,则输出,为空时不输出
val.ifPresent((value)-> System.out.println("the val is "+value));
相当于
if (val.isPresent()) {
System.out.println("the val is " + val.get());
}
练习
public class TradeTest {
Trader raoul = new Trader("Raoul", "Cambridge");
Trader mario = new Trader("Mario", "Milan");
Trader alan = new Trader("Alan", "Cambridge");
Trader brian = new Trader("Brian", "Cambridge");
List<Transaction> 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)
);
//(1) 找出2012年发生的所有交易,并按交易额排序(从低到高)。
@Test
public void test1(){
transactions.stream()
.filter(transaction -> transaction.getYear() == 2012)
.sorted(Comparator.comparing(Transaction::getValue))
.collect(Collectors.toList())
.forEach(System.out::println);
}
//(2) 交易员都在哪些不同的城市工作过?
@Test
public void test2(){
transactions.stream()
.map(Transaction::getTrader)
.map(Trader::getCity)
.distinct()
.forEach(System.out::println);
}
//(3) 查找所有来自于Cambridge的交易员,并按姓名排序。
@Test
public void test3(){
transactions.stream()
.map(Transaction::getTrader)//获取全部交易员
.filter(trader -> trader.getCity().equals("Cambridge"))//筛选出是Cambridge的交易员
.sorted(Comparator.comparing(Trader::getName))//按名字排序
.forEach(System.out::println);
}
//(4) 返回所有交易员的姓名字符串,按字母顺序排序。
@Test
public void test4(){
transactions.stream()
.map(Transaction::getTrader)//获取全部交易员
.map(Trader::getName)
.sorted()
.forEach(System.out::println);
}
//(5) 有没有交易员是在Milan工作的?
@Test
public void test5(){
transactions.stream()
.map(Transaction::getTrader)//获取全部交易员
.filter(trader -> trader.getCity().equals("Milan"))
.distinct()
.forEach(System.out::println);
}
//(6) 打印生活在Cambridge的交易员的所有交易额,。
@Test
public void test6(){
Optional<Integer> cambridgeSumTractionValue = transactions.stream()
.filter(transaction -> transaction.getTrader().getCity().equals("Cambridge"))
.map(Transaction::getValue)
.reduce(Integer::sum);
cambridgeSumTractionValue.ifPresent(val-> System.out.println("cambridgeSumTractionValue is "+val));
}
// (7) 所有交易中,最高的交易额是多少?
@Test
public void test7(){
Optional<Integer> maxTractionValue = transactions.stream()
.map(Transaction::getValue)
.max(Integer::compare);
maxTractionValue.ifPresent((value)-> System.out.println("the maxTractionValue is "+value));
}
//(8) 找到交易额最小的交易。
@Test
public void test8(){
Optional<Integer> minTractionValue = transactions.stream()
.map(Transaction::getValue)
.min(Integer::compare);
minTractionValue.ifPresent((value)-> System.out.println("the minTractionValue is "+value));
}
//(9) 计算交易总额
@Test
public void test9(){
Optional<Integer> sumTractionValue = transactions.stream()
.map(Transaction::getValue)
.reduce(Integer::sum);
sumTractionValue.ifPresent((value)-> System.out.println("the sumTractionValue is "+value));
}
}
平时碰到的问题
//1.1需要取得数组实体里面的所有的downbound<0的groupId,并用于sql查询
StringBuffer stringBuffer =new StringBuffer();
String preGroupIds = null;
collectionStageService.getCollectionStages().stream()
.filter(collectionStageDomain -> collectionStageDomain.getDownbound() < 0)
.map(CollectionStageDomain::getGroupId)
.forEach(x-> stringBuffer.append(x).append(","));
preGroupIds= stringBuffer.substring(0,stringBuffer.length()-1);
//1.2如果只是为了记日志,则可以直接转list 然后日志里面直接输出collect数组
List<Long> collect = collectionStageDomains.stream()
.filter(collectionStageDomain -> collectionStageDomain.getDownbound() < 0)
.map(CollectionStageDomain::getGroupId)
.collect(Collectors.toList());
网友评论