List stream流方式,根据条件修改list中的内容或者过滤(filter,map,flatMap)

** 注意** :list.stream()中的.stream()是将list集合展开,分割成一个一个

1:中间操作
一个流可以后面跟随零个或多个中间操作。其目的主要是打开流,做出某种程度的数据映射/过滤,然后返回一个新的流,交给下一个操作使用。这类操作都是惰性化的,仅仅调用到这类方法,并没有真正开始流的遍历,真正的遍历需等到终端操作时,常见的中间操作有下面即将介绍的 filter、map 等。
2:终端操作
一个流有且只能有一个终端操作,当这个操作执行后,流就被关闭了,无法再被操作,因此一个流只能被遍历一次,若想在遍历需要通过源数据在生成流。终端操作的执行,才会真正开始流的遍历。如下面即将介绍的 count、collect 等。

1:list.stream().filter(dto-> 筛选条件(是一个布尔值)).forEach(dto2-> dto2.setId(“1”));

2:list.stream() .filter(d -> d.getVegitarian()).collect(Collectors.toList());

3:list.stream().filter(Dish::getVegitarian).collect(Collectors.toList());

4:map 流映射(所谓流映射就是将接受的元素映射成另外一个元素)

public static void main(String[] args) {

        List<Map<String, Integer>> list = new ArrayList<>();
        Map<String, Integer> map1 = new HashMap<>();
        map1.put("aa", 1);
        map1.put("bb", 2333);
        map1.put("cc", 3);
        list.add(map1);
        Map<String, Integer> map2 = new HashMap<>();
        map2.put("aa", 1);
        map2.put("bb", 22);
        map2.put("cc", 23);
        list.add(map2);
        Map<String, Integer> map3 = new HashMap<>();
        map3.put("aa", 31);
        map3.put("bb", 32);
        map3.put("cc", 33);
        list.add(map3);
        System.out.println(list);

        Set<String> chartSet=list.stream().filter(a->a.get("aa").equals(1)).map(d->d.get("bb").toString()).collect(Collectors.toSet());
        System.out.println(chartSet);
}

打印结果是

[{aa=1, bb=2333, cc=3}, {aa=1, bb=22, cc=23}, {aa=31, bb=32, cc=33}]
[22, 2333]

4-1:对list操作修改里面的值(类似SQL的select功能)


List<<Map<String, Object>> newList = list.stream().map(d -> {
            d.put("user","李四");
            d.put("age", "18");
            return d;
        }).collect(Collectors.toList());

4-2:筛选list中需要的字段

List<Map<String, Object>> collect = listData.stream().map(dd -> {
            dd.get("name");
            dd.get("chanel");
            return dd;
        }).collect(Collectors.toList());
        System.out.println(collect);

6:distinct 去重

通过distinct方法快速去除重复的元素

		List<Integer> integerList = Arrays.asList(1, 1, 2, 3, 4, 5);

        List<Integer> stream = integerList.stream().distinct().collect(Collectors.toList());

        System.out.println(stream);

打印结果是

[1, 2, 3, 4, 5]

7:实际开发中Stream流式编程flatMap的使用(两层for循环)

flatMap()的作用是对流中的元素进行1对多的转换,然后将结果元素展开为新的流。

这句话的含义是什么?你可以理解为flatMap就是两层for循环处理数据。而返回结果就是flatMap展开的流。

  1. 数据准备
/**
 * 玩具类
 */
@Data
@AllArgsConstructor
public class Toy {

    private String name;

    private double price;
}

-----------------------------------------------------------------------------------------------------------------

@Data
@AllArgsConstructor
public class Boy {
    private String name;

    private int age;

    private List<Toy> toys;
}

-----------------------------------------------------------------------------------------------------------------

@Data
@AllArgsConstructor
public class Student {

    private String name;
    private String schoolName;
    private String className;
}

-----------------------------------------------------------------------------------------------------------------


public class TestStream {
    private static List<Boy> boys = new ArrayList<>();
    private static List<Student> stus = new ArrayList<>();
    static {


        boys.add(new Boy("tom", 12,
                Arrays.asList(
                        new Toy("飞机", 9.1),
                        new Toy("坦克", 7.0),
                        new Toy("小熊", 14.0))));

        boys.add(new Boy("tony", 19,
                Arrays.asList(
                        new Toy("玩具枪", 13.1),
                        new Toy("小汽车", 12.2))));


        stus.add(new Student("tom", "衡水中学", "尖子班"));
        stus.add(new Student("jerry", "黄冈中学", "普通班"));
        stus.add(new Student("dom", "衡水一中", "文科班"));
    }
}
  1. 对元素内部的集合进行处理
    第一个Stream是将boys集合展开,而在flatMap()内部,会将boys集合内部集合再次展开。

其等效于两层for循环,最终得到的结果是n*m给元素。(注:n是外层循环次数,m是内层循环次数)

public static void main(String[] args) {

        //此时是处理第二个循环
        List<Toy> toys = boys.stream().flatMap(
                //将流中元素的数据再次展开
                b -> b.getToys().stream()).
                    collect(Collectors.toList());
        System.out.println(JSON.toJSONString(toys));
//        等效于
        //因为是1:n的关系,所以最终会产生n记录
        List<Toy> tls = new ArrayList<>();
        for (Boy boy : boys) {
            for (Toy toy : boy.getToys()) {
                tls.add(toy);
            }
        }
        //打印数据
        System.out.println(JSON.toJSONString(tls));
  }

当然在flatMap方法内部,可以利用这两个流的元素进行操作。

public static void main(String[] args) {
        List<String> collect1 = boys.stream().flatMap(b -> b.getToys().stream().
                filter(t -> t.getPrice() > 12).
                map(t -> {
                    //即可以操作外层元素也可以操作内层元素
                    return b.getName() + ":" + t.getName();
                })).collect(Collectors.toList());

        System.out.println(JSON.toJSONString(collect1));
        //等效于:
        List<String> tls1 = new ArrayList<>();
        for (Boy boy : boys) {
            for (Toy toy : boy.getToys()) {
                if (toy.getPrice() > 12) {
                    tls1.add(boy.getName() + ":" + toy.getName());
                }
            }
        }
        System.out.println(JSON.toJSONString(tls1));
    }
}
  1. 用于两个集合的合并
    将两个集合合并为一个集合,一般写法需要得借助两层for循环。

而flatMap()操作的一个作用就是将两个集合合并为一个集合,相当于join操作,若没有filter操作,会产生笛卡尔积现象

public static void main(String[] args) {
        List<String> collect = boys.stream().flatMap(b -> stus.stream().
                        //第二层for循环中处理数据
                                filter(s -> b.getName().equals(s.getName())).
                        //将数据放入到一个新的集合中
                                map(Student::getName)
                //结束第二层循环
        ).collect(Collectors.toList());
        System.out.println(JSON.toJSONString(collect));


       //等效于
        List<String> data=new ArrayList<>();
        //双层for循环处理数据
        for (Boy boy : boys) {
            for (Student student : stus) {
                //filter条件
                if(boy.getName().equals(student.getName())){
                    //map子句,将元素放入到新集合中
                    data.add(student.getName());
                }
            }
        }
        System.out.println(JSON.toJSONString(data));
    }

总结:JDK1.8提供了Stream提供的流式操作可以使得开发人员像操作数据库一样操作集合。Map相当于select映射,而flatMap更像join连接

8:实际开发中Stream流式编程flatMap的使用

 
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
 
 
public class FlatMap {
    public static void main(String[] args) {
        //扁平化流
        //找出数组中唯一的字符
        String[] strArray = {"hello", "world"};
 
        //具体实现
        List<String> res = Arrays.stream(strArray)
                .map(w -> w.split(""))
                .flatMap(Arrays::stream)
                .distinct()
                .collect(Collectors.toList());
        System.out.println(res);
 
        //TODO 案例
        System.out.println("--------------------------------");
        //Demo1:给定数组,返回数组平方和(直接使用映射)
        //[1,2,3,4]=>[1,4,9,16]
        Integer[] nums1 = {1, 2, 3, 4};
        List<Integer> nums1List = Arrays.asList(nums1);
        List<Integer> res1 = nums1List.stream().map(i -> i * i).collect(Collectors.toList());
        System.out.println(res1);
 
        System.out.println("--------------------------------");
        //Demo2:给定两数组,返回数组对
        //[1,2,3],[3,4]=>[1,3],[1,4],[2,3],[2,4],[3,3],[3,4]
        Integer[] nums2 = {1, 2, 3};
        Integer[] nums3 = {3, 4};
        List<Integer> nums2List = Arrays.asList(nums2);
        List<Integer> nums3List = Arrays.asList(nums3);
 
        //使用2个map嵌套过滤
        List<int[]> res2 = nums2List.stream().flatMap(i -> nums3List.stream().map(j -> new int[]{i, j})).collect(Collectors.toList());
        System.out.println(res2.size());
 
        System.out.println("--------------------------------");
        //Demo3:针对Demo2和Demo1组合返回总和能被3整除的数对
        //(2,4)和(3,3)是满足条件的
        List<int[]> res3 = nums2List.stream().flatMap(i -> nums3List.stream().filter(j -> (i + j) % 3 == 0).map(j -> new int[]{i, j})).collect(Collectors.toList());
        System.out.println(res3.size());
 
 
    }
}

9: map和flatmap实现一样的效果

		List<String> fun1 = Arrays.asList("one", "two", "three");
        List<String> fun2 = Arrays.asList("four", "five", "six");
        List<List<String>> nestedList = Arrays.asList(fun1, fun2);
        
        nestedList.stream().map(x -> {
            return x.stream().map(a -> a.toUpperCase());
        }).forEach(x ->x.forEach(a->output(a)));
List<String> fun1 = Arrays.asList("one", "two", "three");
        List<String> fun2 = Arrays.asList("four", "five", "six");
        List<List<String>> nestedList = Arrays.asList(fun1, fun2);
        
        nestedList.stream().flatMap(x -> x.stream()).map(x->x.toUpperCase()).forEach(x -> output(x));

你可能感兴趣的:(java,stream,flatMap,filter)