java8 集合结合steam操作实例

集合框架介绍:https://www.runoob.com/java/java-collections.html

java8-streams:https://www.runoob.com/java/java8-streams.html

介绍不过说,上面两个链接可以看一下。正常情况下,for循环就够用了,但是有时候你需要对集合遍历多次才能完成的事情,使用steam进行操作,可能只要一次就可以了,而且代码更加简洁明了。部分示例直接复制自菜鸟教程

具体实例

下面是测试的对象和测试用的公共代码

// 用于测试的对象
public class Student {
    private Integer id; //学生编号
    private String name; // 学生名称
    private int age;    // 学生年龄
    private String cla; // 学生班级
    private int sex;    // 学生性别 0 女 1 男

    public Student(Integer id, String name, int age, String cla, int sex) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.cla = cla;
        this.sex = sex;
    }
	... set和get省略
    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", cla='" + cla + '\'' +
                ", sex=" + sex +
                '}';
    }
}

// 测试的公共代码
        Student student1 = new Student(1, "张1", 12, "一班", 1);
        Student student2 = new Student(2, "张2", 13, "一班", 0);
        Student student3 = new Student(3, "张3", 12, "一班", 1);
        Student student4 = new Student(4, "张4", 14, "二班", 1);
        Student student5 = new Student(5, "张5", 13, "二班", 0);
        Student student6 = new Student(6, "张6", 12, "二班", 1);
        Student student7 = new Student(7, "张7", 11, "三班", 1);
        Student student8 = new Student(8, "张8", 12, "三班", 0);
        Student student9 = new Student(9, "张9", 13, "三班", 1);
        // 异常数据
        Student student10 = new Student(9, "张9", 13, null, 1);
        Student student11 = new Student(9, "张9", 13, "", 0);
        ArrayList<Student> studentList = new ArrayList<>();
        studentList.add(student1);
 		...........
        studentList.add(student11);

stream筛选操作

/**
         * stream 筛选操作一班用于其他操作前对不符合要求的数据进行过滤,当然筛选功能也是可以单独使用的
         * */
        List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl",null);
        List<String> filtered = strings.stream().filter(string -> string != null && !string.isEmpty()).collect(Collectors.toList());
        System.out.println(filtered);// 会调用到AbstractCollection的toString方法  [abc, bc, efg, abcd, jkl]
        // 过滤学生中的异常数据
        List<Student> collect = studentList.stream().filter(student -> student.getCla() != null && !student.getCla().isEmpty()).collect(Collectors.toList());
        // 如果过滤条件比较复杂,你可以这么写
        List<Student> collect1 = studentList.stream().filter(student -> {
            if (student.getCla() != null && !student.getCla().isEmpty()) {
                return false;
            }
            return true;
        }).collect(Collectors.toList());

foreach

/**
 * foreach遍历功能
 * */

Random random = new Random();
IntStream limit = random.ints().limit(10);
// 等价于 int[] ints = limit.toArray();Arrays.stream(ints).forEach(System.out::println);
limit.forEach(System.out::println);
studentList.stream().forEach(System.out::println);

limit

limit 方法用于获取指定数量的流。 以下代码片段使用 limit 方法打印出 10 条数据:

Random random = new Random();
IntStream limit = random.ints().limit(10);
// 等价于 int[] ints = limit.toArray();Arrays.stream(ints).forEach(System.out::println);
limit.forEach(System.out::println);
studentList.stream().forEach(System.out::println);

map

map 方法用于映射每个元素到对应的结果,以下代码片段使用 map 输出了元素对应的平方数:

/**
         * 通俗一点讲,就是集合中每个元素计算后获取到另一个元素,添加到新的集合中
         * */
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        // 获取对应的平方数
        List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());
        // 下面的代码执行会得到学生年龄的集合
        List<Integer> collect2 = studentList.stream().map(i -> i.getAge()).collect(Collectors.toList());
        //复杂操作
        List<Integer> collect3 = studentList.stream().map(i -> {
            return i.getAge() + 1;
        }).collect(Collectors.toList());

sorted

sorted 方法用于对流进行排序。以下代码片段使用 sorted 方法对输出的 10 个随机数进行排序:

Random random = new Random(); random.ints().limit(10).sorted().forEach(System.out::println);

并行(parallel)程序

parallelStream 是流并行处理程序的代替方法。以下实例我们使用 parallelStream 来输出空字符串的数量:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl"); // 获取空字符串的数量 long count = strings.parallelStream().filter(string -> string.isEmpty()).count();


Collectors

Collectors 类实现了很多归约操作,例如将流转换成集合和聚合元素。Collectors 可用于返回列表或字符串:

groupingBy

/**
         * 根据特定字段的不同,将一个集合分成多个集合, 甚至根据多个字段进一步分成多重集合
         * 使用时一般要先进行过滤(筛选),避免异常和得到不想要的结果
         * */
        // 根据性别对学生进行分组, 此处演示,不考虑筛选
        Map<Integer, List<Student>> collect4 = studentList.stream().collect(Collectors.groupingBy(Student::getSex));
        // 根据复杂的条件进行分组 ,此示例 分组后 map的key为 1 和 2
        Map<Integer, List<Student>> collect6 = studentList.stream().collect(Collectors.groupingBy(item -> {
            if (item.getAge() > 12) {
                return 1;
            }
            return 2;
        }));
        // 对学生通过班级分组,再通过性别分组
        Map<String, Map<Integer, List<Student>>> collect5 = studentList.stream().filter(student -> student.getCla() != null && !student.getCla().isEmpty()).
                collect(Collectors.groupingBy(Student::getCla, Collectors.groupingBy(Student::getSex)));

joining

System.out.println("筛选列表: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("合并字符串: " + mergedString);

toMap

/** 
         * Collectors.toMap 将集合中你需要的数据转换成map
         * */
        // 将list转成map,key为 学生名称, value为学生对象 ,这里由于有学生名称重复,抛出异常一般不这么使用
        //Map<String, Student> collect7 = studentList.stream().collect(Collectors.toMap(Student::getName, item -> item));
        
        // 此处和上面相同,但是学生名称重复,会使用后面的学生数据覆盖前面的学生数据
        Map<String, Student> collect8 = studentList.stream().collect(Collectors.toMap(Student::getName, item -> item,(key1, key2) -> key2));
        // 也可以使用单个字段作为Value
        Map<String, String> collect7 = studentList.stream().collect(Collectors.toMap(Student::getName, Student::getCla, (key1, key2) -> key2));
        // 除了覆盖,你还可以这么操作
        Map<String, String> collect9 = studentList.stream().collect(Collectors.toMap(Student::getName, Student::getCla, (key1, key2) -> key2 + "," + key1));
        // 复杂操作
        studentList.stream().collect(Collectors.toMap(Student::getName, item -> {
            return item.getSex() + "," + item.getId();    
        }, (key1, key2) -> key2));

统计

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
 
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
 
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());


    public static void testSum() {
        List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);

        // 没有起始值时返回为Optional类型
        Optional<Integer> sumOptional = integers.stream().reduce(Integer::sum);
        System.out.println(sumOptional.get());

        // 可以给一个起始种子值
        Integer sumReduce = integers.stream().reduce(-1, Integer::sum);
        System.out.println(sumReduce);

        //直接用sum方法
        Integer sum = integers.stream().mapToInt(i -> i).sum();
        System.out.println(sum);
    }

    public static void testMax() {

        //max reduce
        Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
        Integer maxReduce = integerStream.reduce(Integer.MIN_VALUE, Integer::max);
        System.out.println(maxReduce);


        // max
        Stream<Integer> integerStream1 = Stream.of(1, 2, 3, 4, 5);
        OptionalInt max = integerStream1.mapToInt(i -> i).max();
        System.out.println(max.getAsInt());
    }

    public static void testReduce() {
        Stream<Integer> stream = Arrays.stream(new Integer[]{1, 2, null});

        //求集合元素只和
        Integer result = stream.filter(item -> {
            return item != null && item !=1 && item != 2;
        }).reduce(0, Integer::max);
        System.out.println(result);

        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});

        //求和
        stream.reduce((i, j) -> i + j).ifPresent(System.out::println);


        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //求最大值
        stream.reduce(Integer::max).ifPresent(System.out::println);

        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //求最小值
        stream.reduce(Integer::min).ifPresent(System.out::println);

        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});
        //做逻辑
        stream.reduce((i, j) -> i > j ? j : i).ifPresent(System.out::println);

        stream = Arrays.stream(new Integer[]{1, 2, 3, 4, 5, 6, 7});

        //求逻辑求乘机
        int result2 = stream.filter(i -> i % 2 == 0).reduce(1, (i, j) ->{
            return i * j;
        });

        Optional.of(result2).ifPresent(System.out::println);
    }

git操作

1、 下拉指定分支
git clone -b 分支名  git地址


2、git版本控制目录,删除不需要的文件(这里删除所有)
3、 添加忽略文件,提交文件到暂存区,推送到远程

git status -s 查看文件状态
git add .
git commit -m 'commit'
git push

4、 添加新的项目文件
git add .
git commit -m 'commit'
git push

集合拆分

// 代码来自网络(不记得来自那篇博文了), 亲测有效,可以结合steam操作尝试更简便的实现
public static <T> List<List<T>> split(List<T> resList,int count){
        if(resList==null ||count<1)
            return  null ;
        List<List<T>> ret=new ArrayList<List<T>>();
        int size=resList.size();
        if(size<=count){ //数据量不足count指定的大小
            ret.add(resList);
        }else{
            int pre=size/count;
            int last=size%count;
            // 前面pre个集合,每个大小都是count个元素
            for(int i=0;i<pre;i++){
                List<T> itemList=new ArrayList<T>();
                for(int j=0;j<count;j++){
                    itemList.add(resList.get(i*count+j));
                }
                ret.add(itemList);
            }
            // last的进行处理
            if(last>0){
                List<T> itemList=new ArrayList<T>();
                for(int i=0;i<last;i++){
                    itemList.add(resList.get(pre*count+i));
                }
                ret.add(itemList);
            }
        }
        return ret;
    }

需要引入guava

// 例:将集合:list 分割成每个集合25条数据的集合。
        List<String> list = new ArrayList<>(100);
        for (int i = 0; i < 100; i++) {
            list.add("1");
        }
        List<List<String>> partition = Lists.partition(list , 25);
        for (List<String> data : partition) {

            //执行插入
            System.out.println(data.size());
        }

orcale 批量插入操作

你会发现批量操作缺失快很多

// 以下批量操作,操作的数据量不能过大, 毕竟数据传输是有大小限制的,  所以你可能需要对集合进行拆分,拆分注意了,很容易出错,漏了最后一部分
    int insertBatch(@Param("studentList") List<Student> studentList);
    
    <insert id="insertBatch" useGeneratedKeys="false" parameterType="java.util.List">
        INSERT ALL
        <foreach collection="studentList" item="student">
            into student (id, name) VALUES
            (#{student.id},#{student.name})
        </foreach>
        SELECT 1 FROM DUAL
    </insert>