Java 比较两个列表中的元素

Java 比较两个列表中的元素,java,algorithm,list,dictionary,Java,Algorithm,List,Dictionary,我从两家不同的书店得到了两份书名清单。这些标题可以是相同的,但它们的书写方式不同,例如“例如”-“例如”,正如你所看到的,它们是相等的,但一点也不相同 这就是我编写流的原因,它将净化列表中的元素(它将删除空格和特殊字母),并使它们相等,所以在流之后,这两个元素看起来都像“forexmaple”,所以它们现在相等 private List<String> purifyListOfTitles(List<Book> listToPurify) { return

我从两家不同的书店得到了两份书名清单。这些标题可以是相同的,但它们的书写方式不同,例如“例如”-“例如”,正如你所看到的,它们是相等的,但一点也不相同

这就是我编写流的原因,它将净化列表中的元素(它将删除空格和特殊字母),并使它们相等,所以在流之后,这两个元素看起来都像“forexmaple”,所以它们现在相等

private List<String> purifyListOfTitles(List<Book> listToPurify) {
        return listToPurify
                .stream()
                .map(Book::getTitle)
                .map(title -> title.replaceAll("[^A-Za-z]+", ""))
                .collect(Collectors.toList());
    }
例如:

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);
Book a=new Book.BookBuilder().withTitle(“To-jest haha”).build();
Book b=新书.BookBuilder().withTitle(“Bubu”).build();
Book c=新书.BookBuilder().withTitle(“Kiki”).build();
Book d=new Book.BookBuilder().withTitle(“sza.la”).build();
Book e=新书.BookBuilder().withTitle(“Tojest haha”).build();
Book f=新书.BookBuilder().withTitle(“bam”).build();
Book g=新书.BookBuilder().withTitle(“zzz”).build();
Book h=新书.BookBuilder().withTitle(“szaLa”).build();
List list1=新的ArrayList();
清单1.添加(a);
清单1.添加(b);
清单1.添加(c);
清单1.添加(d);
List list2=新的ArrayList();
清单2.添加(e);
清单2.添加(f);
清单2.添加(g);
清单2.添加(h);
Map z=countBooksByTitle(列表1、列表2);
z
map
包含:
{sza.la=2,Bubu=1,zzz=1,Kiki=1,bam=1,To-jest haha=2}

我有两张名单

我想得到一张地图,它将包括这本书的标题和出现的次数

您可以通过单个流链执行此操作:

private Map<String, Long> countBooksByTitle(List<Book> list1, List<Book> list2) {
    return Stream.concat(list1.stream(), list2.stream())
            .map(book -> book.getTitle().replaceAll("[^A-Za-z]+", ""))
            .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
}
更新的计数方法


对算法影响最小的可能解决方案:只要标题与第一个列表中的标题匹配,就可以从第二个列表中删除标题

这样,第二个列表将在for循环之后只包含不匹配的book。 然后,您可以将它们全部添加到地图中,其发生率为1

您应该使用迭代器来浏览列表并删除项

    for (int i = 0; i < purifiedMerlinBookTitles.size(); i++) {
        occurrencesOfIteratedBook = 1;
        iteratedMerlinTitle = purifiedMerlinBookTitles.get(i);
        Iterator<String> it = purifiedEmpikBookTitles.iterator();
        while (it.hasNext()) {
            String iteratedEmpikTitle = it.next();
            if (iteratedMerlinTitle.equals(iteratedEmpikTitle)) {
                occurrencesOfIteratedBook++;
                it.remove();
            }
        }
        bookTitleWithOccurrencesNumber.put(merlinBooks.get(i).getTitle(), occurrencesOfIteratedBook);
    }
    // At this time purifiedEmpikBookTitles contains only unmatched titles
    purifiedEmpikBookTitles.forEach(title -> bookTitleWithOccurrencesNumber.put(title, 1));
    return bookTitleWithOccurrencesNumber;
}
for(int i=0;ibookTitleWithOccurrencesNumber.put(title,1));
返回已发生编号的书名;
}

可能用于计算这两组数据之间的差异。@IronMan您能举例说明吗?Tbh,我考虑了好几个小时,但我看不到最简单的解决方案:/这不是我想要的。现在在地图上,我有净化的标题,但我想有原件,但它可能是我的错,没有说清楚。编辑的问题。你知道有什么解决办法吗?我正在与纯列表进行比较并添加原始标题?我想省略转换为整数,所以我做了:但它将book.getTitle()标记为未解析。我做错了什么?idk,但方法引用是有效的,可能是intellijSame和@Andreas的一些bug。我想要像我在这里做的那样拥有原始标题
bookTitleWithOccurrencesNumber.put(merlinBooks.get(I.getTitle(),occurrencesOfIteratedBook);}
public final class PurifiedTitle implements Comparable<PurifiedTitle> {
    private final String original;
    private final String purified;
    public PurifiedTitle(String title) {
        this.original = title;
        // Purified string has only lowercase letters and digits,
        // with no accents on the letters
        this.purified = Normalizer.normalize(title, Normalizer.Form.NFD)
                .replaceAll("\\P{Alnum}+", "")
                .toLowerCase(Locale.US);
    }
    @Override
    public String toString() {
        return this.original;
    }
    @Override
    public int compareTo(PurifiedTitle that) {
        return this.purified.compareTo(that.purified);
    }
    @Override
    public boolean equals(Object obj) {
        if (! (obj instanceof PurifiedTitle))
            return false;
        PurifiedTitle that = (PurifiedTitle) obj;
        return this.purified.equals(that.purified);
    }
    @Override
    public int hashCode() {
        return this.purified.hashCode();
    }
}
private static Map<String, Integer> countBooksByTitle(List<Book> list1, List<Book> list2) {
    Collator collator = Collator.getInstance(Locale.US);
    collator.setStrength(Collator.PRIMARY);
    return Stream.concat(list1.stream(), list2.stream())
            .collect(Collectors.groupingBy(book -> new PurifiedTitle(book.getTitle()),
                                           Collectors.counting()))
            .entrySet().stream()
            .collect(Collectors.toMap(e -> e.getKey().toString(),
                                      e -> e.getValue().intValue(),
                                      Integer::sum,
                                      () -> new TreeMap<>(collator)));
}
List<Book> list1 = Arrays.asList(
        new Book("To - jest haha"),
        new Book("Bubû"),
        new Book("Kiki"),
        new Book("bam 2"),
        new Book("sza . lä"));
List<Book> list2 = Arrays.asList(
        new Book("Tojest haha"),
        new Book("bam 1"),
        new Book("zzz"),
        new Book("száLa"));
System.out.println(countBooksByTitle(list1, list2));
    for (int i = 0; i < purifiedMerlinBookTitles.size(); i++) {
        occurrencesOfIteratedBook = 1;
        iteratedMerlinTitle = purifiedMerlinBookTitles.get(i);
        Iterator<String> it = purifiedEmpikBookTitles.iterator();
        while (it.hasNext()) {
            String iteratedEmpikTitle = it.next();
            if (iteratedMerlinTitle.equals(iteratedEmpikTitle)) {
                occurrencesOfIteratedBook++;
                it.remove();
            }
        }
        bookTitleWithOccurrencesNumber.put(merlinBooks.get(i).getTitle(), occurrencesOfIteratedBook);
    }
    // At this time purifiedEmpikBookTitles contains only unmatched titles
    purifiedEmpikBookTitles.forEach(title -> bookTitleWithOccurrencesNumber.put(title, 1));
    return bookTitleWithOccurrencesNumber;
}