使用额外的细节来增加对象
问题描述:
我有一个场景,我有一个有序对象列表,我希望用来自组成原始有序对象的另一个对象列表的信息来扩充它。对于前:使用额外的细节来增加对象
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;
}
的设计显然是不正确的(为什么持有在莱杰?首位书+ pricedBooks),但这只是说明一个更大的问题。我试图在一个解决方案也超低效,因为我正在迭代所有我试图增加的每本书的元数据书籍
答
我假设这里有很多东西......但主要重要的是这input.books[i] == pricedBooks[j].book
这是错误的,你实际上想比较PricedBook
和Book
他们的id
s - 这可能是一次改变,这是必须在这里。
首先我计算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());
PricedBook应该扩展Book而不是让它作为参数以 –
开头我在这里使用组合,但是也可以这样做。虽然,为了这个练习,我想忽略任何明显的设计错误,并专注于试图找到一个有效的解决方案 –
你到目前为止尝试过什么?为什么这个'augment'方法仍然是空白的? *我想有一个输出*是一个愿望,所以SO不是正确的地方。 – nullpointer