赞
踩
jva8在java.util.stream包下,通过Stream真正的引入函数式编程,可以对数据进行复杂的查找,过滤映射,提供了高效且易于使用的处理数据的方式,例如想要获取集合中的某些特定元素,在以前需要遍历集合,对每个元素进行筛选代码比较多,通过Stream,一行代码就可以搞定
@Test public void test1(){ //创建Stream的方式 List<Persion> persionList = new ArrayList<>(); persionList.add(new Persion("小明",22,2000.00)); persionList.add(new Persion("小红",34,2500.00)); persionList.add(new Persion("AA",18,1800.00)); persionList.add(new Persion("小强",40,3500.00)); persionList.add(new Persion("小黑",22,2200.00)); persionList.add(new Persion("小花",27,2000.00)); persionList.add(new Persion("bb",16,1500.00)); //1.通过集合中的.stream()获取Stream流,注意该方法返回的是一个顺序流(根据向集合中添加的顺序) Stream<Persion> stream1 = persionList.stream(); //通过集合中的parallelStream()获取一个并行流,有点像通过几个线程同时去取,顺序可能发生改变 Stream<Persion> stream2 = persionList.parallelStream(); //2.通过Arrays工具类中的stream(T[] array)静态方法获取Stream流 //集合转数组 Persion[] perArray = persionList.toArray(new Persion[persionList.size()]); Stream<Persion> stream = Arrays.stream(perArray); //注意点,在使用Arrays中的stream()方法获取Stream流时,根据像方法中传递的 //泛型T不同,其返回的Stream不同 int[] iArray = new int[]{1,4,9}; long[] lArray = new long[]{11l,22l,6l}; double[] dArray = new double[]{7.8,14.3,5.1}; IntStream intStream = Arrays.stream(iArray); LongStream longStream = Arrays.stream(lArray); DoubleStream doubleStream = Arrays.stream(dArray); //3.通过Stream的of()方法创建,将数据传入of()方法中 Stream<Integer> stream3 = Stream.of(1, 2, 3, 4); //4.创建无限Stream流,输出0-10的偶数, //iterate()中0代表开始位置,后面的Lambda传递的是Function<T,T> +2返回 //limit为中止操作,10 //forEach()为执行体 Stream.iterate(0,t -> t +2).limit(10).forEach(System.out :: println); //生成,获取10个随机数 Stream.generate(Math :: random).limit(10).forEach(System.out :: println); }
使用Stream对数据继续操作,例如过滤筛选,映射,排序等,注意点: Stream被称为"惰性求值",在进行中间操作时,如果最终不调用终止,则中间操作无效,在调用终止操作后,若有后续的操作需要重新获取Stream流,否则无效
1)方法概述
2)代码示例
@Test public void test1(){ //persionList是一个List<Persion>集合 //获取Stream流 Stream<Persion> stream = persionList.stream(); //筛选与切片 //1.filter(Predicate p) 过滤,接收 Lambda ,从流中排除某些元素 //获取集合中age大于20的数据 stream.filter(p -> p.getAge()>20).forEach(System.out :: println); //2.limit(n) 截断流,使其元素不超过给定的数量n Stream<Persion> stream2 = persionList.stream(); //获取集合中前三条数据 stream2.limit(3).forEach(System.out :: println); //3.skip(n) 跳过元素,返回一个不包括n以前个数的元素,若流中不足n个数据则返回就返回一个空流 //去掉集合中前3个元素 persionList.stream().skip(3).forEach(System.out :: println); //4.distinct() 筛选,通过流所生成元素的hashCode()和equals()去除重复元素 //去重 persionList.stream().distinct().forEach(System.out :: println); }
1)方法概述
2)代码示例
@Test public void test2(){ //1.map(Function f) 接收一个函数作为参数,将元素映射成其它形式或获取信息, //该函数会被应用到每个元素上,并将其映射到新的元素 //map()会依次对Stream中的每个元素执行 //示例1,将集合中所有字符串转换为大写 List<String> stringList = Arrays.asList("aa", "bb", "cc"); stringList.stream().map(str -> str.toUpperCase()).forEach(System.out :: println); //示例2,获取集合姓名包含"小"的员工的姓名 Stream<String> ageStream = persionList.stream().map(Persion::getName); ageStream.filter(name -> name.contains("小")).forEach(System.out :: println); //2.flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流 //然后把所有流连接成一个流,与map()方法的区别有点像集合中的add(),与addAll() //假设调用add方法向集合中添加另外一个集合是会变成[obj1, obj2, obj3,List[obj1,obj2,obj3]] //如果调用addAll(),则会重新组合为一个集合,而不是集合作为集合类型元素存在 //假设通过map()获取的数据是Stream<Stream<T>>,此时如果想要继续过滤就有点麻烦,可以通过flatMap() //例如调用下面自定义的fromStringToStream(String str)方法,返回多个Stream流, Stream<Stream<Character>> streamStream = stringList.stream().map(ArrayTest::fromStringToStream); //输出stringList中的所有char字符,由于调用ArrayTest类中中的fromStringToStream()方法 //返回的是Stream<Stream<Charcter>>,需要两层farEach() streamStream.forEach(s -> { s.forEach(System.out :: println); }); //使用flamtMap,则会将多个Stream流重新组合为一个 Stream<Character> characterStream = stringList.stream().flatMap(ArrayTest::fromStringToStream); characterStream.forEach(System.out :: println); } //将String字符串,转换为char集合,并将char集合转换为Stream流返回 public static Stream<Character> fromStringToStream(String str){ ArrayList<Character> list = new ArrayList<>(); for(Character c : str.toCharArray()){ list.add(c); } return list.stream(); }
//1.使用map转换为其它类型 List<ResponseDataDTO> responseDataDTOS = result.stream().map(a -> { ResponseDataDTO responseDataDTO = new ResponseDataDTO(); responseDataDTO.setC00(""); responseDataDTO.setC01(a.getRmtype()); responseDataDTO.setC02(a.getRate1().toString()); responseDataDTO.setC03(""); responseDataDTO.setC04(""); responseDataDTO.setC05(""); responseDataDTO.setC06(a.getRatecode()); responseDataDTO.setC07(""); responseDataDTO.setC08(a.getRate1().toString()); responseDataDTO.setC09(a.getPackages()); return responseDataDTO; }).collect(Collectors.toList()); //2.使用map+flatMap多list合并 List<String> accntList = searchcheckin.getData().getList() .stream() .filter(o -> !CollectionUtils.isEmpty(o.getList())) .map(OrderRespDTO::getList) .flatMap(Collection::stream) .filter(occ -> !CollectionUtils.isEmpty(occ.getGuests())) .map(OccupationDTO::getGuests) .flatMap(Collection::stream) .filter(g -> StringUtils.isNotBlank(g.getAccNt())) .map(GuestDTO::getAccNt) .distinct() .collect(Collectors.toList());
1)方法概述
2)代码示例
@Test public void test3(){ //排序 //1.sorted() 自然排序 List<Integer> integers = Arrays.asList(12, 34, 20, 70, 60); integers.stream().sorted().forEach(System.out::println); //如果想要自定义类对象实现自然排序,该类需要实现Comparator接口,制定排序规则否则报错 //否则使用sorted定制排序 //2.sorted(Comparator com) 定制排序(如果年龄相等则使用工资排序) persionList.stream().sorted((p1, p2) ->{ int ageVal = Integer.compare(p1.getAge(),p2.getAge()); if(ageVal != 0){ return ageVal; }else { return Double.compare(p1.getSalary(), p2.getSalary()); } }).forEach(System.out :: println); }
1)方法概述
2) 代码示例
@Test public void test4() { List<Persion> persionList = new ArrayList<>(); persionList.add(new Persion("小明", 22, 2000.00)); //add()...... //一下的操作中都可以在加入中间操作实现过滤后再进行终止 //1.allMatch(Predicate p) 检查元素是否匹配,所有都是true,才是true //判断是否集合中的所有年龄都大于18岁 Boolean b1 = persionList.stream().allMatch(p -> p.getAge() > 18); //2.anyMatch(Predicate p) 检查是否有一个元素匹配,有一个为true则为true //判断集合中是否有工资大于5000 Boolean b2 = persionList.stream().anyMatch(p -> p.getSalary() > 5000); //3.noneMatch(Predicate p) 检查是否没有匹配的 //判断集合中是否有叫小明的,如果有则返回false boolean b3 = persionList.stream().noneMatch(p -> p.getName().contains("小明")); //4.findFirst 返回第一个元素,Option<> Optional<Persion> persionOptional = persionList.stream().findFirst(); //5.findAny 返回当前流中任意元素 Optional<Persion> anyPersion = persionList.stream().findFirst(); //6.count 返回当前流中元素个数 //获取工资超过2000的个数 long count = persionList.stream().filter(p -> p.getSalary()>2000.00).count(); //7.max(Comparator c) 返回当前流中最大的元素 //返回最大工资的 Optional<Persion> max = persionList.stream().max((p1, p2) -> Double.compare(p1.getSalary(), p2.getSalary())); //min(Comparator c) 返回最小的元素 //返回年龄最小的 Optional<Persion> min = persionList.stream().min((p1, p2) -> Integer.compare(p1.getAge(), p2.getAge())); //返回最小年龄 persionList.stream().map(p -> p.getAge()).min(Integer :: compare); //8.forEach(Consumer c) 内部迭代 persionList.stream().forEach(System.out :: println); }
1)方法概述
2)代码示例
@Test public void test5(){ //1.reduce(T identity, BinaryOperator) 将六种的元素结合起来得到一个值并返回 //查看BinaryOperator源码进行分析 //BinaryOperator继承BiFunction<T,T,T>接口,该接口传递两个T类型参数,返回一个T类型参数 //刚好符合Integer与Dubbo中的sum方法 //计算1-10的自然数的和 List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10); Integer reduce = list.stream().reduce(0, Integer::sum); //普通方式 Integer reduce2 = list.stream().reduce(0, (i1, i2) -> i1 + i2); //2.reduce(BinaryOperator) //获取集合中工资总和 List<Persion> persionList = new ArrayList<>(); persionList.add(new Persion("小明", 22, 2000.00)); //add()... Optional<Double> reduce1 = persionList.stream().map(Persion::getSalary).reduce(Double::sum); //普通方式 persionList.stream().map(Persion::getSalary).reduce((d1, d2) -> d1+d2); }
1)方法概述
StreamAPI 收集 Collectors,将过滤终止的Stream结果数据收集为其他类型,与Stream收集终止操作配合使用
2)代码示例
@Test public void test6(){ //1.collection(Collector c); 配合Collector中的静态方法,将Stream过滤终止后的数据 //收集为其他类型,例如List, set等 List<Persion> persionList = new ArrayList<>(); persionList.add(new Persion("小明", 22, 2000.00)); //add()...... //查找工资大于2000的员工返回List,或set List<Persion> pList = persionList.stream().filter(p -> p.getSalary()>2000).collect(Collectors.toList()); pList.forEach(System.out :: println); //返回set集合 Set<Persion> collect = persionList.stream().filter(p -> p.getSalary() > 2000).collect(Collectors.toSet()); //返回Collection,根据toCollection中的类型来决定返回值的类型 ArrayList<Persion> collect1 = persionList.stream().filter(p -> p.getSalary() > 2000) .collect(Collectors.toCollection(ArrayList::new)); }
Map<String, List<NewRoomStatusDataRespDTO>> map = respList.stream().collect(Collectors.groupingBy(NewRoomStatusDataRespDTO::getBldCd));
//返回集合中userName等于"aaa"的数据,如果不存在返回null;
User user = userList.stream().filter(u -> u.getUserName().equals("aaa")).findAny().orElse(null);
//获取集合中对象元素指定属性
List<String> orderNoList=list.stream().map(Order::getOrderNo).collect(Collectors.toList());
private List<RoomStatusAllDataRespDTO> generateRoomsAllStateResult(List<DayRoomsStateDTO> roomStateList) { //1.value为原数据,重复key覆盖 Map<String, DayRoomsStateDTO> map1 = roomStateList.stream().collect(Collectors.toMap(DayRoomsStateDTO::getDate, Function.identity(), (oldKey, newKey) -> newKey)); //2.value为通过Stream数据封装出的类型(Map中的value为 RoomStateDTO是DayRoomsStateDTO::getRoom返回的数据类型),重复key覆盖 Map<String, RoomStateDTO> map2 = roomStateList.stream().collect(Collectors.toMap(DayRoomsStateDTO::getDate, DayRoomsStateDTO::getRoom, (oldKey, newKey) -> newKey)); //3.value为通过Stream数据封装出的类型,重复key放入list中 Map<String, List<RoomStateDTO>> map = roomStateList.stream().collect(Collectors.toMap(DayRoomsStateDTO::getDate, dayRoomsStateDTO -> { ArrayList<RoomStateDTO> list = new ArrayList<>(); list.add(dayRoomsStateDTO.getRoom()); return list; }, (oldList, newList) -> { oldList.addAll(newList); return oldList; })); //4.转map并排序 TreeMap<String, List<Working>> collect = workings.stream().collect(Collectors.toMap(Working::getInvoicePage, e -> { ArrayList<Working> list = new ArrayList<>(); list.add(e); return list; }, (oldList, newList) -> { oldList.addAll(newList); return oldList; }, () -> new TreeMap<>(Comparator.comparing(Integer::valueOf)))); return null; }
private List<OccupationDTO> getOccupationDTO(PmsOrderBean order, List<PmsOccupationGuest> occGuestList) { if (CollectionUtils.isEmpty(occGuestList)) { return null; } //1.由于三方返回订单信息以入住人为维度,先通过房间号进行分组 //(groupingBy会把相同key的元素合并成一个List作为Map的value) Map<String, List<PmsOccupationGuest>> guestMap = occGuestList.stream() .collect(Collectors.groupingBy(PmsOccupationGuest::getRoomNo)); //2.转换为对应占房类型,并根据房间号去重 List<OccupationDTO> occupateionList = occGuestList.stream() .map(occ -> { return occ.convertOccupationDTO(order.getOrderState()); }) .collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<OccupationDTO>(Comparator.comparing(OccupationDTO::getRoomNo))), ArrayList::new)); //3.拿到占房结构信息后遍历,通过房间号获取分组中对应信息,填充入住人信息 occupateionList.forEach(occ -> { List<GuestDTO> gList = guestMap.get(occ.getRoomNo()).stream() .map(PmsOccupationGuest::convertGuestDTO) .collect(Collectors.toList()); occ.setGuests(gList); }); return occupateionList; }
//1.在使用groupingBy分组时(groupingBy会把相同key的元素合并成一个List作为Map的value)
Map<String, List<PmsOccupationGuest>> guestMap = occGuestList.stream()
.collect(Collectors.groupingBy(PmsOccupationGuest::getRoomNo));
//可以使用上方的groupingBy进行优化(因为重复key时也是接近添加到list中作为map的value) Map<String, List<GuestDTO>> guestMap = pmsOrderList.stream() .map(this::convertGuestDTO) .map(Map::entrySet) .flatMap(Collection::stream) .collect(Collectors.toMap(Map.Entry::getKey, entry -> { ArrayList<GuestDTO> list = new ArrayList<>(); list.add(entry.getValue()); return list; }, (oldList, newList) -> { oldList.addAll(newList); return oldList; })); //也可以将该方法修改为返回一个GuestDTO对象,而不是Map private Map<String, GuestDTO> convertGuestDTO(GetArrivingResp.OrderListBean orderPms) { Map<String, GuestDTO> guestMap = new HashMap<>(); GuestDTO guest = new GuestDTO(); guest.setGuestName(orderPms.getName()); guest.setGuestMobile(orderPms.getMobilePhone()); guest.setGuestCardNum(orderPms.getIdentity()); guest.setCheckInTime(DateUtil.stringToLongSecond(orderPms.getBeginTime())); guest.setCheckOutTime(DateUtil.stringToLongSecond(orderPms.getEndTime())); //0 预登记 1预定 2 入住 3离店 10取消 guest.setGuestStatus(this.orderStatus(orderPms.getAbleCheckIn())); //guest.setAccNt(orderPms.getAccountNo()); guestMap.put(orderPms.getUnionAccountNo(), guest); return guestMap; } //然后使用: 表示先按照getUnionAccountNo进行分组, //分组后,通过 Collectors.mapping()对每个分组中的数据进行类型转换拿到GuestDTO //最终拿到 Map<String, List<GuestDTO>> Map<String, List<GuestDTO>> gMap = pmsOrderList.stream() .collect(Collectors.groupingBy(GetArrivingResp.OrderListBean::getUnionAccountNo, Collectors.mapping(orderBean -> this.convertGuestDTO(orderBean), Collectors.toList())));
// 只要集合中有一个匹配,就返回 true boolean anyMatch(Predicate<? super T> predicate); // 集合中所有元素都匹配,才返回 true boolean allMatch(Predicate<? super T> predicate); // 集合中所有元素都不匹配,返回 true boolean noneMatch(Predicate<? super T> predicate); public class Main { public static void main(String[] args) { List<String> list = MyUtil.getList(); System.out.println("集合中的所有元素是否都以 a 开头"); System.out.println(list.stream().allMatch(s -> s.startsWith("a"))); System.out.println("集合中是否存在元素以 a 开头"); System.out.println(list.stream().anyMatch(s -> s.startsWith("a"))); System.out.println("集合中的元素是否都不以 a 开头(相当于 allMatch 的取反):"); System.out.println(list.stream().noneMatch(s -> s.startsWith("a"))); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。