2017-10-15 39 views
1

我有一个场景,我有一个有序对象列表,我希望用来自组成原始有序对象的另一个对象列表的信息来扩充它。对于前:使用额外的细节来增加对象

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),但这只是说明一个更大的问题。我试图在一个解决方案也超低效,因为我正在迭代所有我试图增加的每本书的元数据书籍

+0

PricedBook应该扩展Book而不是让它作为参数以 –

+0

开头我在这里使用组合,但是也可以这样做。虽然,为了这个练习,我想忽略任何明显的设计错误,并专注于试图找到一个有效的解决方案 –

+0

你到目前为止尝试过什么?为什么这个'augment'方法仍然是空白的? *我想有一个输出*是一个愿望,所以SO不是正确的地方。 – nullpointer

回答

1

我假设这里有很多东西......但主要重要的是这input.books[i] == pricedBooks[j].book这是错误的,你实际上想比较PricedBookBook他们的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());