有时候我们在sql里面查询出来的数据想要进行分组操作,但是不想要改变sql想要偷懒,这时候就可以通过java代码侧去对数据进行分组操作.

/*这里返回的数据就是
[MyTable(name=张三, age=1), MyTable(name=李四, age=2),
 MyTable(name=王五, age=3), MyTable(name=李四, age=4), 
 MyTable(name=田七, age=5)]*/
List<MyTable> myTables = myTableDao.selectAll();

/*我们这里想通过name进行分组,返回值是一个Map键是需要分组的值
就是下面的MyTable.getName为键,因为分完组后一个名字下面
可能有很多值,所以是个List作为值*/
Map<String,List<MyTable>> map = 
myTables.stream().conllect(Collectors.groupingBy(MyTable::getName));

/*有时候需求是只要分完组里面某个字段的最小值或者最大值
那么就可以通过这种方式实现
这里的键就是跟上面一样是分组的字段值,
值这里通过Collectors.minBy获取里面最小值,这里面需要对
数据进行排序,我们使用Comparator.comparing通过age字段
进行升序排列
*/
Map<String,Options<MyTable>> map = 
myTables.stream().conllect(Collectors.groupingBy(MyTable::getName,
Collectors.minBy(Comparator.comparing(MyTable::getAge))));

// reduce的相关操作这里的order对象里面重写了toString用的是JSON.toJSONString();
Order order = new Order();
order.setId("123);
order.setName("张三");
List<String> list = new ArrayList<>();
for (int i = 0; i < 10; i++) {
   list.add(String.valueOf(i));
}
order.setList(list);
// 这里的TypeReference就是里面的泛型就是要转换的对象类型
Map<String,String> map = JSON.parseObject(order.toString(),
										new TypeReference<Map<String,String>>()){});
/*这里的reduce就是把里面的参数进行指定操作返回值是optional这里的orElse是从optional里面有
值返回值没有就返回""*/
String str = map.entrySet().stream.map(m -> m.getKey() + "=" + m.getValue())
											.reduce((p1,p2) -> p1 + "&" + p2).orElse("");
System.out.println(str);
// 结果:
name=张三&id=123&list=["0","1","2","3","4","5","6","7","8","9"]

// 还有两个参数的方法
String str = map.entrySet().stream.map(m -> m.getKey() + "=" + m.getValue())
			   								.reduce("哈哈哈",(p1,p2) -> p1 + "&" + p2);
// 这里多出来的参数就是初始值结果:
哈哈哈&name=张三&id=123&list=["0","1","2","3","4","5","6","7","8","9"]

之前使用通过很多次Collectors.toMap今天发现他有三个参数的构造方法来浅尝一下

public static void main(String[] args) {
        List<Order> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            Order order = new Order();
            order.setId(String.valueOf(i));
            order.setName("张三"+i);
            list.add(order);
        }

        // 这里添加一个重复key的数据到list
        Order order = new Order();
        order.setId("8");
        order.setName("测试重复key");
        list.add(order);

		// 这里的第三个参数意思就是 如果当前map的key发生了重复那么就用旧数据
		// v1:代表旧数据 v2:代表新数据
        Map<String, String> collect = list.stream().
        collect(Collectors.toMap(Order::getId, Order::getName, (v1, v2) -> v1));
        System.out.println(collect);
    }

结果:
{0=张三0, 1=张三1, 2=张三2, 3=张三3, 4=张三4, 5=张三5, 6=张三6, 7=张三7, 8=张三8, 9=张三9}

Map<String, String> collect = list.stream().
collect(Collectors.toMap(Order::getId, Order::getName, (v1, v2) -> v2));
System.out.println(collect);
结果:
{0=张三0, 1=张三1, 2=张三2, 3=张三3, 4=张三4, 5=张三5, 6=张三6, 7=张三7, 8=测试重复key, 9=张三9}

今天写代码用到关于grouping by但是我们知道grouping by之后出来的value是一个list对象我想加工成list其他类型可以用下面的方式

public static void main(String[] args) {
        List<ShopIdAndPictureUrl> list = new ArrayList<>();
        list.add(new ShopIdAndPictureUrl("123","234"));
        list.add(new ShopIdAndPictureUrl("123","456"));
        list.add(new ShopIdAndPictureUrl("123","789"));

        Map<String, List<String>> collect = list.stream()
                /*
                * 对list进行转换 
                * 参数一: key是shopId
                * 参数二: 对原本的valueList<ShopIdAndPictureUrl>进行加工
                *       加工参数一: 要加工的哪个数据
                *       加工参数二: 最终要什么类型
                * */
                
                .collect(Collectors.groupingBy(ShopIdAndPictureUrl::getShopId, 
                        Collectors.mapping(ShopIdAndPictureUrl::getPictureSufUrl, Collectors.toList())));
        System.out.println(collect);
结果:{123=[234, 456, 789]}