java8中流(Stream)的简单使用

275 阅读5分钟

多种语言描述你喜欢的女子类型

汉语:

身高小于165的中国女子

英语:

china girl whose height less than 165

结构化查询语言:

select * from world_user where country='china' and height<165 and sex='female'

id	name	sex	age	height	country
4	辣目洋子	female	27	162	china

js:

world_user.filter(p=>'china'==p.country&&165>p.height).forEach(p=>console.log(p))

{age: 27, sex: 'female', name: '辣目洋子', height: 162, country: 'china'}

java:

worldUserList.stream().filter(p->165>p.height&&"female".equals(p.sex)&&"china".equals(p.country)).forEach(p->System.out.println(p));

WorldUser(age=27, country=china, height=162, name=辣目洋子, sex=female)

我看透了这世界

我曾经看过一部电影《后会无期》,住酒店的人会收到一些人物属性卡片,每一个卡片后面对应着一个人。广告:买洛川苹果,看高清图片

找它的过程是信息筛选的过程:信息会记录在卡片、电子表格(excel)、网站、数据库等等地方,今天我们分享的是java中通过流提供的方法方法

java8中流(Stream)的简单使用

既然看透了,那它们一样喽?

是的,我们讲从sql的角度(条件查询,字段筛选,去重,分组统计,排序)来抛砖引玉的讲一下stream

我要每一个人的详细信息(查询所有)

sql:

select * from world_user

java:

    //全表查询
    public List<WorldUser> selectAll(){
        List<WorldUser> worldUserList=getList();
        return worldUserList.stream().collect(Collectors.toList());
    }

共产主义接班人(字段筛选)

sql:

select name from world_user where country='china'

java:

        List<String> nameList =
                worldUserList.stream() //获取流
                        .filter(p -> "china".equals(p.country)) //将满足判定条件的元素组成流
                        .map(p -> p.name) // 方法返回值组成流,”p->p.name"这种写法属于lambda表达式
                        .collect(Collectors.toList()); // 生成一个新的 List

我要所有姑娘的信息(条件查询)

sql:

select * from world_user where sex='female'

java:

    //条件查询
    public List<WorldUser> selectFemale(){
        List<WorldUser> worldUserList=getList();
        return worldUserList.stream().filter(p->"female".equals(p.getSex())).collect(Collectors.toList());
    }

她们在哪儿(去重)

sql:

select distinct country from world_user where sex='female'

java:

    //where is she
    public static List<String> distinct() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream()
                .map(p -> p.getCountry())
                .distinct()
                .collect(Collectors.toList());
    }

每个国家有多少人(分组统计)

sql:

select country,count(*) from world_user group by country

java:

    //where is she
    public static List<String> distinct() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream()
                .map(p -> p.getCountry())
                .distinct()
                .collect(Collectors.toList());
    }

每个国家,不同性别有多少人(分组统计)

sql:

SELECT country,sex,count(*) FROM world_user GROUP BY country,sex

java:

    //多字段分组
    public static Map<String,Map<String,Long>> groupByMultiColumn() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream()
                .collect(Collectors.groupingBy(p->p.getCountry(),
                        Collectors.groupingBy(p->p.getSex(),Collectors.counting())));
    }

谁个子最高(排序)

sql:

SELECT * FROM world_user order by height desc

java:

    //排序
    public static List<WorldUser> sortByHeight() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream()
                .sorted((p1,p2)-> p2.getHeight().compareTo(p1.getHeight()))
                .collect(Collectors.toList());
    }

获得宠物的名字(先到这吧)

sql:

java:

    /**
     * [
     *        {
     * 		"name": "刘亦菲",
     * 		"pets": [
     *            {
     * 				"name": "小猪佩奇"
     *            },
     *            {
     * 				"name": "小猪乔治"
     *            }
     * 		]
     *    },
     *    {
     * 		"name": "花泽香菜",
     * 		"pets": [
     *            {
     * 				"name": "小羊苏西"
     *            }
     * 		]
     *    }
     * ]
     * @return
     */
    public static List<String> getUserPetsName() {
        return getUserWithPets().stream()
                .flatMap(p->p.getJSONArray("pets").toJavaList(JSONObject.class).stream())
                .map(q->q.getString("name")).collect(Collectors.toList());
    }

基础数据准备及完整的代码

数据库:

CREATE TABLE `world_user`  (
  `id` int(0) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '姓名',
  `sex` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '性别',
  `age` int(0) NULL DEFAULT NULL COMMENT '年龄',
  `height` int(0) NULL DEFAULT NULL COMMENT '身高',
  `country` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '国家',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of world_user
-- ----------------------------
INSERT INTO `world_user` VALUES (1, '刘亦菲', 'female', 35, 170, 'china');
INSERT INTO `world_user` VALUES (2, 'lisa', 'female', 25, 165, 'korea');
INSERT INTO `world_user` VALUES (3, '花泽香菜', 'female', 33, 157, 'japan');
INSERT INTO `world_user` VALUES (4, '辣目洋子', 'female', 27, 162, 'china');
INSERT INTO `world_user` VALUES (5, '石原里美', 'female', 36, 157, 'japan');
INSERT INTO `world_user` VALUES (6, '胡歌', 'male', 40, 185, 'china');
INSERT INTO `world_user` VALUES (7, '彭于晏', 'male', 40, 182, 'china');

通过sql查询可以获得json数据

SELECT JSON_ARRAYAGG(JSON_OBJECT('name', name, 'sex',sex,'age',age,'height', height,'country',country)) from world_user;

js:

var world_user=上面sql执行的结果;

world_user.filter(p=>'china'==p.country&&165>p.height).forEach(p=>console.log(p))

完整的java代码:

package com.example.collection;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import lombok.Data;

import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class StreamTest {
    public static void main(String[] args) {

        System.out.println(selectAll());
        System.out.println(chineseName());
        System.out.println(selectFemale());
        System.out.println(killList());
        System.out.println(distinct());
        System.out.println(groupBySimple());
        System.out.println(groupBy());
        System.out.println(groupByMultiColumn());
        System.out.println(sortByHeight());
        System.out.println(whoIsShe());
        System.out.println(getUserPetsName());

        List<WorldUser> worldUserList = getList();

        worldUserList.stream().filter(p -> 165 > p.height).filter(p -> "female".equals(p.sex)).filter(p -> "china".equals(p.country)).forEach(p -> System.out.println(p));

    }

    //她是谁
    public static List<WorldUser> whoIsShe(){
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream()
                .filter(p -> 165 > p.height && "female".equals(p.sex) && "china".equals(p.country))
                .collect(Collectors.toList());
    }

    //全表查询
    public static List<WorldUser> selectAll() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream().collect(Collectors.toList());
    }

    //她是谁
    public static List<String> chineseName(){
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream() //获取流
                        .filter(p -> "china".equals(p.country)) //将满足判定条件的元素组成流
                        .map(p -> p.name) // 方法返回值组成流,”p->p.name"这种写法属于lambda表达式
                        .collect(Collectors.toList()); // 生成一个新的 List
    }

    //条件查询
    public static List<WorldUser> selectFemale() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream().filter(p -> "female".equals(p.getSex())).collect(Collectors.toList());
    }

    //字段筛选
    public static List<String> killList() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream()
                .filter(p -> "male".equals(p.getSex()))
                .map(p -> p.getName())
                .collect(Collectors.toList());
    }

    //where is she
    public static List<String> distinct() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream()
                .map(p -> p.getCountry())
                .distinct()
                .collect(Collectors.toList());
    }

    //简单分组(group by)
    public static Map<String,List<WorldUser>> groupBySimple() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream()
                .collect(Collectors.groupingBy(p->p.getCountry()));
    }

    //统计分组(group by)
    public static Map<String,Long> groupBy() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream()
                .collect(Collectors.groupingBy(p->p.getCountry(),Collectors.counting()));
    }

    //多字段分组
    public static Map<String,Map<String,Long>> groupByMultiColumn() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream()
                .collect(Collectors.groupingBy(p->p.getCountry(),
                        Collectors.groupingBy(p->p.getSex(),Collectors.counting())));
    }

    //排序
    public static List<WorldUser> sortByHeight() {
        List<WorldUser> worldUserList = getList();
        return worldUserList.stream()
                .sorted((p1,p2)-> p2.getHeight().compareTo(p1.getHeight()))
                .collect(Collectors.toList());
    }







    //获得宠物名称
    /**
     * [
     *        {
     * 		"name": "刘亦菲",
     * 		"pets": [
     *            {
     * 				"name": "小猪佩奇"
     *            },
     *            {
     * 				"name": "小猪乔治"
     *            }
     * 		]
     *    },
     *    {
     * 		"name": "花泽香菜",
     * 		"pets": [
     *            {
     * 				"name": "小羊苏西"
     *            }
     * 		]
     *    }
     * ]
     * @return
     */
    public static List<String> getUserPetsName() {
        return getUserWithPets().stream()
                .flatMap(p->p.getJSONArray("pets").toJavaList(JSONObject.class).stream())
                .map(q->q.getString("name")).collect(Collectors.toList());
    }

    public static List<WorldUser> getList() {
        String ss = "[{\"age\": 35, \"sex\": \"female\", \"name\": \"刘亦菲\", \"height\": 170, \"country\": \"china\"}, {\"age\": 25, \"sex\": \"female\", \"name\": \"lisa\", \"height\": 165, \"country\": \"korea\"}, {\"age\": 33, \"sex\": \"female\", \"name\": \"花泽香菜\", \"height\": 157, \"country\": \"japan\"}, {\"age\": 27, \"sex\": \"female\", \"name\": \"辣目洋子\", \"height\": 162, \"country\": \"china\"}, {\"age\": 36, \"sex\": \"female\", \"name\": \"石原里美\", \"height\": 157, \"country\": \"japan\"}, {\"age\": 40, \"sex\": \"male\", \"name\": \"胡歌\", \"height\": 185, \"country\": \"china\"}, {\"age\": 40, \"sex\": \"male\", \"name\": \"彭于晏\", \"height\": 182, \"country\": \"china\"}]";
        List<WorldUser> worldUserList = JSONObject.parseArray(ss, WorldUser.class);
        return worldUserList;
    }

    public static List<JSONObject> getUserWithPets() {
        String ss = "[{\"name\":\"刘亦菲\",\"pets\":[{\"name\":\"小猪佩奇\"},{\"name\":\"小猪乔治\"}]},{\"name\":\"花泽香菜\",\"pets\":[{\"name\":\"小羊苏西\"}]}]";
        return JSONArray.parseArray(ss).toJavaList(JSONObject.class);
    }
}

@Data
class WorldUser {
    Integer age;
    String country;
    Integer height;
    String name;
    String sex;
}

参考文档

Lambda 表达式有何用处?如何使用? - 知乎 (zhihu.com)

[译] 一文带你玩转 Java8 Stream 流,从此操作集合 So Easy - 掘金 (juejin.cn)