我有一个场景,我有一个有序对象列表,我希望用另一个组成原始有序对象的对象列表中的信息来扩充它们。例如:
if ("Annual".equalsIgnoreCase(quest)) {
choice = 1;
} else if ("Quarterly".equalsIgnoreCase(quest)) {
choice = 4;
} else if ("Monthly".equalsIgnoreCase(quest)) {
choice = 12;
} else {
//you need to do something here.
}
所以,给定一个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>
,其中包含一个完整的售价书籍集合,该集合尊重{{{{{{ 1}}但是来自相应的(id =相同)PriceLedger
List<Ledger>
设计显然不正确(为什么在Ledger中首先拿着书籍+售价书?)但这只是为了说明一个更大的问题。我尝试解决方案也非常低效,因为我正在迭代我试图增加的每本书的所有元数据书籍
答案 0 :(得分:1)
我在这里假设了很多东西......但最重要的一点是,input.books[i] == pricedBooks[j].book
这个PricedBook
是错误的,你实际上想要通过他们的Book
和id
进行比较{1}} 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());