java - 如何实现图书排名 - JAVA
问题描述
有人可以帮我在 JAVA 中实现一种方法,获得书店最畅销的 50 本书吗?
这是Bookstore
课程:
public class Bookstore implements Serializable {
private static final long serialVersionUID = -3099048826035606338L;
private boolean populated;
private final List<Country> countryById;
private final Map<String, Country> countryByName;
private final List<Address> addressById;
private final Map<Address, Address> addressByAll;
private final List<Customer> customersById;
private final Map<String, Customer> customersByUsername;
private final List<Author> authorsById;
private final List<Book> booksById;
private final List<Cart> cartsById;
private final List<Order> ordersById;
private final LinkedList<Order> ordersByCreation;
OrderLine
是另一个包含订单详细信息的类,例如:
private final Book book;
private final int qty;
private final double discount;
private final String comments;
我开始这样做:(我必须考虑订单状态 SHIPPED 和书的主题),但我不知道这是否正确或下一步该怎么做,例如,如何通过 bookId 和 order 对数量求和畅销书排行榜:
public List<Book> getBestSellers(String subject) {
ArrayList<Book> bestSellers = new ArrayList<Book>();
for (Order order : ordersById) {
if (order.getStatus().equalsIgnoreCase("SHIPPED")) {
for (int i=0; i<order.getLines().size(); i++){
解决方案
首先,您需要收集数量为 1 的所有书籍Map<Book, Integer>
。然后你应该对它们进行排序并限制只有 50 个。
它会是这样的:
List<Book> books = orders.stream().filter(PhilippBooks::isShipped)
.flatMap(Order::lines)
.collect(Collectors.toMap(OrderLine::getBook, OrderLine::getQuantity, Integer::sum))
.entrySet()
.stream()
.sorted(PhilippBooks.reversed())
.limit(50)
.peek(System.out::println)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
并确保您的 Book 类正确实现了hashCode函数。在地图上收集书籍是必要的。
完整的代码示例:
public class PhilippBooks {
public static void main(String[] args) {
Book tolstoy = new Book("Tolstoy");
Book dostoevsky = new Book("Dostoevsky");
Book london = new Book("London");
List<Order> orders = List.of(
new Order("SHIPPED", new OrderLine(tolstoy, 3), new OrderLine(london, 6)),
new Order("SHIPPED", new OrderLine(tolstoy, 2), new OrderLine(dostoevsky, 10)),
new Order("OTHER", new OrderLine(tolstoy, 1), new OrderLine(london, 1), new OrderLine(dostoevsky, 1)));
List<Book> books = orders.stream().filter(PhilippBooks::isShipped)
.flatMap(Order::lines)
.collect(Collectors.toMap(OrderLine::getBook, OrderLine::getQuantity, Integer::sum))
.entrySet()
.stream()
.sorted(PhilippBooks.reversed())
.limit(50)
.peek(System.out::println)
.map(Map.Entry::getKey)
.collect(Collectors.toList());
System.out.println(books);
}
private static Comparator<Map.Entry<Book, Integer>> reversed(){
return (o1, o2) -> o2.getValue() - o1.getValue();
}
private static boolean isShipped(Order order){
return order.getStatus().equalsIgnoreCase("SHIPPED");
}
private static class Book {
private final String name;
private Book(String name) {
this.name = name;
}
@Override
public String toString() {
return "Book{" +
"name='" + name + '\'' +
'}';
}
}
private static class Order {
private final String status;
private final List<OrderLine> lines;
public Order(String status, OrderLine... lines) {
this(status, Arrays.asList(lines));
}
public Order(String status, List<OrderLine> lines) {
this.status = status;
this.lines = lines;
}
public Stream<OrderLine> lines(){
return lines.stream();
}
public String getStatus() {
return status;
}
}
private static class OrderLine {
private final Book book;
private final int quantity;
public OrderLine(Book book, int quantity) {
this.book = book;
this.quantity = quantity;
}
public Book getBook() {
return book;
}
public int getQuantity() {
return quantity;
}
}
}
推荐阅读
- c++ - 斐波那契数列和的最后一位 (m,n)
- sharepoint - Sharepoint 列表适配器 - ssis 2010
- angular - Angular 7:如何在订阅中转换查询参数?
- github - 没有迷彩的 Github 图片
- r - 是否可以在 AWS SageMaker 实例上使用 RStudio IDE
- wordpress - 错误 3097:VPSProtocol 值超出有效范围。应该在 2.00 和 3.00 之间
- python - 在 SQLAlchemy 中加入两个 text() 语句
- angular - tslint 吐出圈复杂度错误
- android - 打开谷歌地图并返回用户选择的位置
- database - Cassandra cql 相当于 sql 中的 over()