我有一个问题,我想保留原始的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
答案 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
类中的equals
和Item
方法。
此方法为 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);
}
}