我有一个场景,我有一个有序对象列表,我希望用来自组成原始有序对象的另一个对象列表中的信息来扩充它。例如:
class Ledger {
int id;
List<Book> books; // ordered collection of books
List<PricedBook> pricedBooks; //empty originally
}
class PriceLedger {
int id;
Set<PricedBook> booksWithPrices;
}
class Book {
int id;
String text;
}
class PricedBook {
Book book;
double price;
public PricedBook (final Book book, double price) {
this.book = book;
this.price = price;
}
}
所以,给定一个 List<Ledger>
和一个 List<PriceLedger>
, 我想要输出 List<Ledger>
其中包含一个已填写的 pricedBooks 集合,这些集合尊重在 List<Book>
中找到的书籍的原始顺序。但使用来自相应(id = 相同)PriceLedger 的增强价格信息
public List<Ledger> augment(List<Ledger> input, List<PriceLedger> metadata)
{
List<Ledger> result = new ArrayList<>();
for (Ledger l : input)
{
result.add(augmentLedger(l, metadata));
}
}
public Ledger augmentLedger(Ledger input, List<PriceLedger> metadata)
{
List<PricedBook> result = new ArrayList<>();
List<PricedBook> pricedBooks = metadata.stream().map(PriceLedger::booksWithPrices).flatMap(Collection::stream).collect(Collections.toList());
for (int i = 0; i < input.books.size(); i ++) {
for (int j = 0; j < pricedBooks.size(); j++) {
if (input.books[i] == pricedBooks[j].book) {
result.add(pricedBooks[j]);
}
}
}
Ledger l = new Ledger().setPricedBooks(result)
return l;
}
设计显然不正确(为什么在 Ledger 中首先持有 books + pricedBooks?)但这只是为了说明一个更大的问题。我对解决方案的尝试也非常低效,因为我正在为我试图扩充的每本书迭代所有元数据书籍
最佳答案
我在这里假设了很多事情......但最重要的是这个 input.books[i] == pricedBooks[j].book
是你真正想要的错误通过 id
比较 PricedBook
和 Book
- 这可能是这里必须进行的一次更改。
首先我计算我将执行查找的 map
,这对于输入的每个值都是相同的,因此只需要计算一次:
// PriceLedger::Id --> [ PricedBook::Id, PricedBook ]
Map<Integer, Map<Integer, PricedBook>> map = metadata.stream()
.collect(Collectors.toMap(
PriceLedger::getId,
pl -> pl.getBooksWithPrices().stream()
.collect(Collectors.toMap(
pb -> pb.getBook().getId(),
Function.identity()))));
一旦就绪,剩下的就很容易了。对于每个 Ledger
,在映射中查找对应的 PriceLedger
;然后为每本书搜索相应的 PriceBook
。
引入 Map
应该会大大加快速度,因为我们只执行哈希查找;而不是反复查找所需的条目。
input.stream()
.map(l -> {
List<Book> withoutPrice = l.getBooks();
List<PricedBook> withPrice = withoutPrice.stream()
.map(b -> {
return map.get(l.getId()).get(b.getId());
})
.collect(Collectors.toList());
return new Ledger(l.getId(), l.getBooks(), withPrice);
})
.collect(Collectors.toList());
关于java - 使用额外的细节增强对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46751307/