如何存储一定数量的数组列表中的重复项

时间:2019-01-11 13:38:09

标签: java arraylist frequency

我有一个问题,我想保留原始的arraylist,并要制作两个单独的arraylist,其中一个不包含任何重复项,另一个不包含第一个arraylist中的项数。 例如:

ArrayList<Item> items = new ArrayList<Item>(); 
ArrayList<Item> items2 = new ArrayList<Item>(); 
ArrayList<Item> occurences = new ArrayList<Item>();

items[0, 1, 2] would have bandana bandana bandana
items2[0] would have bandana
occurences[0] would have 3

7 个答案:

答案 0 :(得分:0)

下面的代码显示了您需要的示例,但不是Item(我不知道您是否将其作为示例或它是您的类),而是使用String来存储元素和Integer以用于发生。

要存储没有重复的元素,我建议使用Set

public static void main(String[] args) {
    ArrayList<String> items = new ArrayList<String>(); 
    ArrayList<String> items2 = new ArrayList<String>(); 
    ArrayList<Integer> occurences = new ArrayList<Integer>();

    items.add("bandana");
    items.add("bandana");
    items.add("bandana");

    items2.addAll(new HashSet<>(items)); // create Hashset to remove duplicates and add again to Arraylist
    occurences.add(items.size()); // add size of items list as first element

    items.forEach(System.out::println);   // Print: "bandana" "bandana" "bandana"
    items2.forEach(System.out::println);  // Print: "bandana"
    occurences.forEach(System.out::println); // Print: 1
}

答案 1 :(得分:0)

这可能不是最有效的方法,但是我会尝试这样的事情:

ArrayList<Item> items = new ArrayList<Item>(); 
ArrayList<Item> items2 = new ArrayList<Item>(); 
ArrayList<Item> occurences = new ArrayList<Item>();

for(int i=0; i<items.size(); i++)
{
    Item x = items.get(i);
    int count=1;

    if(!items2.contains(x))
    {
        items2.add(x);
        for(int j=i+1; j<items.size(); j++)
        {
            if(items2.get(j)==x)
                count++;
        }
        ocurrences.add(count);
    }
}

对于事件列表,您可能希望将Item更改为int

答案 2 :(得分:0)

集合中没有重复

对于应该没有重复项的集合,请使用Set<Item>而不是ArrayList<Item>Set数据结构将不存储重复项。由于Item是您创建的自定义对象,因此您将需要覆盖hashCode类中的equalsItem方法。

此方法为 O(1)-比保留ArrayList<Item>并对其进行迭代并搜索重复项(将为 O(n)< / strong>)。

发生次数

对于出现问题,不要将项目放在ArrayList<Item>中,而应将它们放在Map<Item,Integer>中。这会将项目映射到它出现的次数。

使用地图,您将需要获取密钥,即即将添加的Item。如果它已经存在于地图中,只需在该键的值(出现次数)上添加一个即可。

如果它们的密钥尚不存在(这是此Item的第一次插入地图),只需将其添加到地图,并将值设置为1。

使用地图也将是一种更有效的解决方案,因为如果{{1则为 O(1),而不是 O(n) }}。

示例:

ArrayList<Item>

答案 3 :(得分:0)

假设您可以使用Java 8流,也可以这样进行:

List<String> items = Arrays.asList("bandana", "helmet", "bandana",
                           "bandana", "silk hat", "basecap", "silk hat");

Map<String, Long> result = items.stream().collect(
    Collectors.groupingBy(Function.identity(), Collectors.counting()));

System.out.println(result); //prints {silk hat=2, helmet=1, bandana=3, basecap=1}

您将拥有一个以项目本身为键(Function.identity())和事件数为值(Collectors.counting())的地图,而不是两个具有不同值和出现次数的列表。

答案 4 :(得分:0)

这是我使用流和lambda函数的解决方案。我将occurence修改为Map<Item, Integer>,以便我们可以对每一项进行计数

items.stream().forEach( i -> {
    if (!items2.contains(i)) {
        items2.add(i);
    }
    occurences.merge(i, 1, Integer::sum);
});

this answer中发现了merge的非常酷的用法。由于我们不知道Item是什么,所以我改用String进行了测试,以便equals等正常工作

答案 5 :(得分:0)

使用lambda获取不同值的列表:

ArrayList items2 = items.stream().distinct().collect(Collectors.toCollection(ArrayList::new)));

如果我正确理解,您需要为每个项目出现的次数:

Map<Item, Integer> m = new HashMap();
items.stream().forEach(k-> m.merge(k,1, Integer::sum));
ArrayList occurrences = new ArrayList(m.values());

occurrences中的顺序不反映项目的顺序。

答案 6 :(得分:0)

您可以如下生成每个列表,

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;

public class Main
{
  public static void main(String args[])
  {
    ArrayList<String> items = new ArrayList<>();
    ArrayList<String> items2 = new ArrayList<>();
    ArrayList<Integer> occurrences = new ArrayList<>();

    items.addAll(Arrays.asList("bandana", "bandana", "bandana", "abc", "abc"));

    items2.addAll(new LinkedHashSet<>(items));

    for (String item : items2)
    {
      occurrences.add(Collections.frequency(items, item));
    }

    System.out.println(items);
    System.out.println(items2);
    System.out.println(occurrences);
  }
}