【发布时间】:2019-12-07 05:32:37
【问题描述】:
我从两家不同的书店获得了 2 个书名列表。这些标题可以相同,但写法不同,例如“例如”-“例如”,正如您所见,它们是相等的,但根本不相等。
这就是为什么我编写了流,它将从列表中净化元素(它将删除空格和特殊字母)并使它们相等,因此在流之后两者看起来都像“forexmaple”,所以它们现在是相等的。
private List<String> purifyListOfTitles(List<Book> listToPurify) {
return listToPurify
.stream()
.map(Book::getTitle)
.map(title -> title.replaceAll("[^A-Za-z]+", ""))
.collect(Collectors.toList());
}
问题是...我想获得一张地图,其中包含原始标题和书籍出现次数(最多出现 2 次,默认为 1)。 我编写了比较两个标题的算法,并将第一个书店的标题添加到地图,但我必须从第二个添加,但不知道如何获得这个标题。
说清楚……
我将第一家书店的书名与第二家书店的每个书名进行比较,如果相等,则添加 +1,如果 for 循环结束,我将添加第一家书店的迭代标题和出现次数.但是第二家书店的书名只有一次出现呢?我知道第一家书店的迭代标题索引,因此我可以使用.get(i) 方法从原始列表(带有未纯化的标题)中获取该标题,但我不知道第二家书店的迭代标题索引以获取原始标题。
我看到的唯一解决方案是,首先将 tite 与第二个书店的每个书名进行比较,然后将书名与第一个书店的每个书名进行比较,但这不是最佳解决方案......或者以某种方式取消了列表。
总而言之,我只有第一家书店的地图标题,如何添加第二家书店的标题被省略。 我想在地图中有原始标题(例如,纯化的是 houseisbig,但原始的是 House - is big)!我正在与纯化列表进行比较并添加原始标题。
班级:
package bookstore.scraper.rankingsystem;
import bookstore.scraper.Bookstore;
import bookstore.scraper.book.Book;
import bookstore.scraper.book.scrapingtypeservice.CategorizedBookService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static java.util.stream.Collectors.toMap;
@Slf4j
@Component
public class CategorizedBooksRankingService {
private final CategorizedBookService categorizedBookService;
@Autowired
public CategorizedBooksRankingService(CategorizedBookService categorizedBookService) {
this.categorizedBookService = categorizedBookService;
}
public Map<String, Integer> getRankingForCategory(String category) {
Map<Bookstore, List<Book>> bookstoreWith15CategorizedBooks = chooseGetterImplementationByCategory(category);
List<Book> merlinBooks = bookstoreWith15CategorizedBooks.get(Bookstore.MERLIN);
List<Book> empikBooks = bookstoreWith15CategorizedBooks.get(Bookstore.EMPIK);
List<String> purifiedMerlinBookTitles = purifyListOfTitles(merlinBooks);
List<String> purifiedEmpikBookTitles = purifyListOfTitles(empikBooks);
Map<String, Integer> bookTitleWithOccurrencesNumber =
prepareTitleAndOccurrencesMap(merlinBooks, empikBooks, purifiedMerlinBookTitles, purifiedEmpikBookTitles);
return getSortedLinkedHashMappedByValue(bookTitleWithOccurrencesNumber);
}
private Map<String, Integer> prepareTitleAndOccurrencesMap(List<Book> merlinBooks, List<Book> empikBooks, List<String> purifiedMerlinBookTitles, List<String> purifiedEmpikBookTitles) {
Map<String, Integer> bookTitleWithOccurrencesNumber = new LinkedHashMap<>();
int occurrencesOfIteratedBook;
String iteratedMerlinTitle;
for (int i = 0; i < purifiedMerlinBookTitles.size(); i++) {
occurrencesOfIteratedBook = 1;
iteratedMerlinTitle = purifiedMerlinBookTitles.get(i);
for (String iteratedEmpikTitle : purifiedEmpikBookTitles) {
if (iteratedMerlinTitle.equals(iteratedEmpikTitle))
occurrencesOfIteratedBook++;
}
bookTitleWithOccurrencesNumber.put(merlinBooks.get(i).getTitle(), occurrencesOfIteratedBook);
//how to add to bookTitleWithOccurrencesNumber map book titles from second bookstore that are not equal to any of title
}
return bookTitleWithOccurrencesNumber;
}
private List<String> purifyListOfTitles(List<Book> listToPurify) {
return listToPurify
.stream()
.map(Book::getTitle)
.map(title -> title.replaceAll("[^A-Za-z]+", ""))
.collect(Collectors.toList());
}
private Map<String, Integer> getSortedLinkedHashMappedByValue(Map<String, Integer> mapToSort) {
return mapToSort.entrySet()
.stream()
.sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
.collect(
toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2,
LinkedHashMap::new));
}
private Map<Bookstore, List<Book>> chooseGetterImplementationByCategory(String category) {
if (category.equals("crimes"))
return categorizedBookService.get15BooksFromCrimeCategory();
if (category.equals("romances"))
return categorizedBookService.get15BooksFromRomanceCategory();
if (category.equals("fantasies"))
return categorizedBookService.get15BooksFromFantasyCategory();
if (category.equals("guides"))
return categorizedBookService.get15BooksFromGuidesCategory();
if (category.equals("biographies"))
return categorizedBookService.get15BooksFromBiographiesCategory();
else {
log.error(category + " is invalid category");
throw new IllegalArgumentException();
}
}
}
例子:
Book a = new Book.BookBuilder().withTitle("To - jest haha").build();
Book b = new Book.BookBuilder().withTitle("Bubu").build();
Book c = new Book.BookBuilder().withTitle("Kiki").build();
Book d = new Book.BookBuilder().withTitle("sza . la").build();
Book e = new Book.BookBuilder().withTitle("Tojest haha").build();
Book f = new Book.BookBuilder().withTitle("bam").build();
Book g = new Book.BookBuilder().withTitle("zzz").build();
Book h = new Book.BookBuilder().withTitle("szaLa").build();
List<Book> list1 = new ArrayList<>();
list1.add(a);
list1.add(b);
list1.add(c);
list1.add(d);
List<Book> list2 = new ArrayList<>();
list2.add(e);
list2.add(f);
list2.add(g);
list2.add(h);
Map<String,Long> z = countBooksByTitle(list1,list2);
z map 包含:{sza . la =2, Bubu=1, zzz=1, Kiki=1, bam=1, To - jest haha =2}
【问题讨论】:
-
也许使用
Set.removeAll来计算两组之间的差异。 -
@IronMan 你能说明一下吗? Tbh,我考虑了好几个小时,但我看不到最简单的解决方案:/
标签: java algorithm list dictionary