Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用额外的细节在适当的位置扩充对象_Java_Algorithm_Java 8 - Fatal编程技术网

Java 使用额外的细节在适当的位置扩充对象

Java 使用额外的细节在适当的位置扩充对象,java,algorithm,java-8,Java,Algorithm,Java 8,我有一个场景,其中我有一个有序对象列表,我希望用组成原始有序对象的另一个对象列表中的信息来补充它。例如: class Ledger { int id; List<Book> books; // ordered collection of books List<PricedBook> pricedBooks; //empty originally } class PriceLedger { int id; Set<PricedBook&

我有一个场景,其中我有一个有序对象列表,我希望用组成原始有序对象的另一个对象列表中的信息来补充它。例如:

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;
   }
}
分类账{
int-id;
列出书籍;//有序收集书籍
列出pricedBooks;//原为空
}
类别价格分类帐{
int-id;
定价;
}
课堂用书{
int-id;
字符串文本;
}
类定价书{
书籍;
双倍价格;
公共定价书(最终图书,双倍价格){
这本书;
这个价格=价格;
}
}
因此,给定一个
列表
和一个
列表
,我希望有一个
列表
的输出,其中包含一个已填写的pricedBooks集合,该集合与
列表
中找到的书籍的原始顺序有关,但包含相应(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;
}
公共列表扩充(列表输入、列表元数据)
{
列表结果=新建ArrayList();
对于(分类账l:输入)
{
结果.添加(增加分类账(l,元数据));
}
}
公共分类账(分类账输入、列表元数据)
{
列表结果=新建ArrayList();
List pricedBooks=metadata.stream().map(PriceLedger::booksWithPrices).flatMap(Collection::stream).collect(Collections.toList());
for(int i=0;i

这种设计显然是不正确的(为什么在分类账中首先要保留图书+价格图书?),但这只是为了说明一个更大的问题。我试图在中找到一个解决方案也是非常低效的,因为我正在迭代我试图扩充的每本书的所有元数据书

我假设这里有很多东西。。。但是最重要的一点是,这个
输入。books[i]==pricedBooks[j]。book
是错误的,你实际上想通过它们的
id
s来比较
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()))));

PricedBook应该扩展Book,而不是一开始就把它作为参数。我在这里使用的是合成,但是的,它也可以这样做。不过,就为了这个练习,我想忽略任何明显的设计错误,集中精力寻找一个有效的解决方案。到目前为止,您尝试了什么?为什么
augment
方法仍然是空的?我想要一个输出是一种欲望,所以不是放置它的正确位置。@nullpointer我尝试了我试图描述的暴力解决方案above@JohnBaum我仍然没有看到问题中的尝试。我希望你能理解
 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());