有时候我们在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]}