动态关键字排序和查询使用什么结构


public class Book {
private Long id;
private Long quantity;
}

我想要一张对书籍数量进行排序的地图,但数量总是变化的,当数量变化时如何排序,小心不同的书的数量可能是相同的。

我认为您可以使用两个地图,一个用于存储所有书籍,另一个用于按数量排序。

以下是测试代码:

import java.util.*;
public class Book {
private Long id;
private Long quantity;
public Book(Long id, Long quantity) {
this.id = id;
this.quantity = quantity;
}
public Long getId() {
return id;
}
public Long getQuantity() {
return quantity;
}
@Override
public String toString() {
return "Book{" +
"id=" + id +
", quantity=" + quantity +
'}';
}
}
class Books {
// id -> Book
private final Map<Long, Book> books = new HashMap<>();
// q -> idSet
private final SortedMap<Long, Set<Long>> sortedMap = new TreeMap<>(Comparator.reverseOrder());
public void save(Book book) {
Book old = books.get(book.getId());
books.put(book.getId(), book);
// q -> idSet
Long q = book.getQuantity();
Set<Long> idSet = sortedMap.get(q);
if (null == idSet) {
idSet = new HashSet<>();
}
idSet.add(book.getId());
// sorted by quantity
sortedMap.put(q, idSet);
// remove id from old idSet
if (old != null) {
Long oq = old.getQuantity();
if (!q.equals(oq)) {
idSet = sortedMap.get(oq);
idSet.remove(book.getId());
if(idSet.isEmpty()){
sortedMap.remove(oq);
}
}
}
}
public Book getBook(Long id) {
return books.get(id);
}
@Override
public String toString() {
StringBuilder b = new StringBuilder("Books{n");
sortedMap.forEach((q, idSet) -> {
b.append(String.format("%8d: ", q));
idSet.forEach(id -> b.append(books.get(id)).append(' '));
b.append('n');
});
b.append('}');
return b.toString();
}
public static void main(String[] args) {
Books t = new Books();
t.save(new Book(1L, 1L));
t.save(new Book(2L, 2L));
t.save(new Book(3L, 3L));
t.save(new Book(4L, 1L));
System.out.println(t);
t.save(new Book(1L, 10L));
System.out.println(t);
t.save(new Book(2L, 20L));
System.out.println(t);
t.save(new Book(3L, 30L));
System.out.println(t);
t.save(new Book(5L, 50L));
System.out.println(t);
t.save(new Book(4L, 50L));
System.out.println(t);
}
}

由于这里有两个(通常(互斥操作(标识和排序(,您必须将其中一个与另一个分离,正如@Echo Ma所建议的那样。然而,我建议应该在需要时进行排序,而不是在插入时。

让我们假设您有一个集合或映射bookSet,其中您有Bookid的唯一实例,并且每个实例都由某个进程根据其数量进行更新。然后,你可以只在需要时使用以下代码进行基于数量的排序:

Comparator<Book> comparator = ( book1, book2 ) -> {
long b1q = book1.getQuantity().longValue();
long b2q = book2.getQuantity().longValue();
if( b1q > b2q ) return 1;
else if( b1q == b2q ) return 0;
else return -1;
};
/* When you want the books list sorted by quantity, do this. (Assuming bookSet that has the list of unique Book instances with current quantities.) */
List<Book> sortedByQty = new ArrayList<>( bookSet );
Collections.sort( sortedByQty, comparator );

最新更新