Book数据
[
{
"name": "name-1-1",
"category": 1,
"level": 1,
"author": "a",
"price": 22.0
},
{
"name": "name-1-2",
"category": 1,
"level": 2,
"author": "b",
"price": 21.0
},
{
"name": "name-1-3",
"category": 1,
"level": 3,
"author": "c",
"price": 22.0
},
{
"name": "name-2-1",
"category": 2,
"level": 1,
"author": "d",
"price": 22.0
},
{
"name": "name-3-1",
"category": 3,
"level": 1,
"author": "e",
"price": 22.0
},
{
"name": "name-1-1--",
"category": 1,
"level": 1,
"author": "f",
"price": 22.0
},
{
"name": "name-2-1--",
"category": 2,
"level": 1,
"author": "g",
"price": 22.0
},
{
"name": "name",
"category": 1,
"level": 1,
"author": "h",
"price": 22.0
}
]
转成 每个category每个level book详情
{
"1":[
{
"level":1,
"books":[
{
"name":"name-1-1",
"price":22,
"author":"a"
},
{
"name":"name-1-1--",
"price":22,
"author":"f"
},
{
"name":"name",
"price":22,
"author":"h"
}
]
},
{
"level":2,
"books":[
{
"name":"name-2-1",
"price":22,
"author":"d"
},
{
"name":"name-2-1--",
"price":22,
"author":"g"
}
]
},
{
"level":3,
"books":[
{
"name":"name-3-1",
"price":22,
"author":"e"
}
]
}
],
"2":[
{
"level":1,
"books":[
{
"name":"name-1-2",
"price":21,
"author":"b"
}
]
}
],
"3":[
{
"level":1,
"books":[
{
"name":"name-1-3",
"price":22,
"author":"c"
}
]
}
]
}
自定义Collector
@Data
public class Book {
private String name;
private Integer category;
private Integer level;
private String author;
private Double price;
@Data
public static class Group {
private Integer level;
private List<BookInfo> books;
@Data
public static class BookInfo {
private String name;
private Double price;
private String author;
}
}
public static class MyCollector implements Collector<Book, Table<Integer, Integer, List<Group.BookInfo>>, Map<Integer, List<Group>>> {
@Override
public Supplier<Table<Integer, Integer, List<Group.BookInfo>>> supplier() {
return HashBasedTable::create;
}
@Override
public BiConsumer<Table<Integer, Integer, List<Group.BookInfo>>, Book> accumulator() {
return (table, book) -> {
List<Group.BookInfo> books = table.get(book.getCategory(), book.getLevel());
if (books == null) {
books = new ArrayList<>();
}
Group.BookInfo info = new Group.BookInfo();
info.setAuthor(book.getAuthor());
info.setName(book.getName());
info.setPrice(book.getPrice());
books.add(info);
table.put(book.getCategory(), book.getLevel(), books);
};
}
@Override
public BinaryOperator<Table<Integer, Integer, List<Group.BookInfo>>> combiner() {
return (a, b) ->
Stream.concat(a.cellSet().stream(), b.cellSet().stream())
.collect(Tables.toTable(Table.Cell::getRowKey,
Table.Cell::getColumnKey,
Table.Cell::getValue,
(x, y) -> {
x.addAll(y);
return x;
}, HashBasedTable::create));
}
@Override
public Function<Table<Integer, Integer, List<Group.BookInfo>>, Map<Integer, List<Group>>> finisher() {
return (table) -> {
Map<Integer, List<Group>> result = new HashMap<>();
table.columnMap().forEach((key, value) -> {
List<Group> groups = value.entrySet().stream()
.map(t -> {
Group group = new Group();
group.setBooks(t.getValue());
group.setLevel(t.getKey());
return group;
}).collect(Collectors.toList());
result.put(key, groups);
});
return result;
};
}
@Override
public Set<Characteristics> characteristics() {
return EnumSet.of(Characteristics.CONCURRENT);
}
}
}
测试
private List<Book> books;
private Gson gson;
@Before
public void before() {
gson = new Gson();
InputStream inputStream = this.getClass().getResourceAsStream("/book.json");
try (BufferedReader buffer = new BufferedReader(new InputStreamReader(inputStream))) {
String json = buffer.lines().collect(Collectors.joining());
Gson gson = new Gson();
TypeToken<List<Book>> typeToken = new TypeToken<>() { };
books = gson.fromJson(json, typeToken.getType());
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void myCollectorTest() {
Map<Integer, List<Book.Group>> collect = books.stream().collect(new Book.MyCollector());
System.out.println(gson.toJson(collect));
}
源码地址
https://github.com/googalAmbition/googol/blob/master/java-base/src/main/java/com/tcoding/demo/base/stream/Book.java