在多个数组上获取相同的元素值

the*_*bie 1 java android java-7

我一直在搜索关于这个问题,大多数只有两个数组比较的问题有一个嵌套循环.我的问题非常相似,但规模更大.假设我的应用程序中有100或1000个用户,并且每个用户都有他想要的项目列表.像这样的东西

    User1 = {apple,orange,guava,melon,durian}
    User2 = {apple, melon,banana,lemon,mango}
    User3 = {orange,carrots,guava,melon,tomato}
    User4 = {mango,carrots,tomato,apple,durian}
    .
    .
   Nuser = ...
Run Code Online (Sandbox Code Playgroud)

我想看看所有用户数组中列出了多少苹果或橙子.所以我基本上比较但是规模更大.数据也不是静态的,用户可以从开发人员的知识中输入未知的水果,但是根据用户的知识,他们可以把它放在那里,这样可以有多个用户可以放置这个未知的水果,但系统仍然可以弄清楚这个未知项目被列出了多少.请记住,这是一个动态的.根据应用程序的受欢迎程度,用户可以达到例如100个用户.我不能在这里做嵌套循环.

PS这不是确切的问题,但它是我能想到解释我的问题的最简单的场景.

PS:只是为了澄清,我不打算像番石榴一样使用第三方库.我在proguard上遇到了问题.

War*_*ard 5

编辑

只是看到原始海报不能使用Java 8,这是一个遗憾,因为这将真的很容易!

Java 7解决方案

final Map<String, Integer> occurencesByFruit = new HashMap<>();
for (User user : users) {
    String[] fruits = user.getFruits();
    for (String fruit : fruits) {
        final Integer currentCount = occurencesByFruit.get(fruit);
        if (currentCount == null) {
            occurencesByFruit.put(fruit, 1);
        } else {
            occurencesByFruit.put(fruit, currentCount + 1);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Java 8解决方案

我将用户流flatMap()转换为实际的水果元素,然后Collectors.groupingBy()与下游收集器一起使用Collectors.counting().

这将为您提供Map键是水果的位置,值是您所有用户中每个水果的出现次数.

List<User> users = Arrays.asList(/* ... */);

final Map<String, Long> occurencesByFruit = users.stream()
        .map(User::getFruits)
        .flatMap(Arrays::stream)
        .collect(Collectors.groupingBy(f -> f, Collectors.counting()));
Run Code Online (Sandbox Code Playgroud)