【发布时间】:2012-11-05 22:01:55
【问题描述】:
我有一个ArrayList,其中包含许多记录,其中一列包含气体名称,如 CO2 CH4 SO2 等。现在我只想检索不同的气体名称(唯一),而不需要从 ArrayList 重复。怎么办?
【问题讨论】:
-
我会更新标签。这是一个 Java 问题,我认为它与 jsf 和 primefaces 无关......
我有一个ArrayList,其中包含许多记录,其中一列包含气体名称,如 CO2 CH4 SO2 等。现在我只想检索不同的气体名称(唯一),而不需要从 ArrayList 重复。怎么办?
【问题讨论】:
您应该使用Set。 Set 是不包含重复项的 Collection。
如果您有一个包含重复项的 List,您可以获得这样的唯一条目:
List<String> gasList = // create list with duplicates...
Set<String> uniqueGas = new HashSet<String>(gasList);
System.out.println("Unique gas count: " + uniqueGas.size());
注意:此HashSet 构造函数通过调用元素的equals() 方法来识别重复项。
【讨论】:
java: no suitable constructor found for HashSet。知道为什么会这样吗?
LinkedHashSetstackoverflow.com/a/8712770/32453
方法distinct 是一个中间操作,它过滤流并只允许不同的值(默认使用 Object::equals 方法)传递给下一个操作。
我在下面为您的情况写了一个示例,
// Create the list with duplicates.
List<String> listAll = Arrays.asList("CO2", "CH4", "SO2", "CO2", "CH4", "SO2", "CO2", "CH4", "SO2");
// Create a list with the distinct elements using stream.
List<String> listDistinct = listAll.stream().distinct().collect(Collectors.toList());
// Display them to terminal using stream::collect with a build in Collector.
String collectAll = listAll.stream().collect(Collectors.joining(", "));
System.out.println(collectAll); //=> CO2, CH4, SO2, CO2, CH4 etc..
String collectDistinct = listDistinct.stream().collect(Collectors.joining(", "));
System.out.println(collectDistinct); //=> CO2, CH4, SO2
【讨论】:
Set喜欢接受的答案。我可能一开始就没有List
我希望我能正确理解您的问题:假设值的类型为 String,最有效的方法可能是转换为 HashSet 并对其进行迭代:
ArrayList<String> values = ... //Your values
HashSet<String> uniqueValues = new HashSet<>(values);
for (String value : uniqueValues) {
... //Do something
}
【讨论】:
ArrayList values = ... // your values
Set uniqueValues = new HashSet(values); //now unique
【讨论】:
这是一种直接的方法,无需使用自定义比较器或类似的东西:
Set<String> gasNames = new HashSet<String>();
List<YourRecord> records = ...;
for(YourRecord record : records) {
gasNames.add(record.getGasName());
}
// now gasNames is a set of unique gas names, which you could operate on:
List<String> sortedGasses = new ArrayList<String>(gasNames);
Collections.sort(sortedGasses);
注意:使用TreeSet 而不是HashSet 将给出直接排序的arraylist,上面的Collections.sort 可以被跳过,但TreeSet 在其他方面效率较低,因此使用@987654326 通常会更好,而且很少会更糟@即使需要排序。
【讨论】:
您可以使用它来制作唯一的列表
ArrayList<String> listWithDuplicateValues = new ArrayList<>();
list.add("first");
list.add("first");
list.add("second");
ArrayList uniqueList = (ArrayList) listWithDuplicateValues.stream().distinct().collect(Collectors.toList());
【讨论】:
当我执行相同的查询时,我很难根据自己的情况调整解决方案,尽管之前的所有答案都有很好的见解。
当必须获取唯一对象列表而不是字符串时,这是一种解决方案。
假设有一个 Record 对象列表。 Record 类只有String 类型的属性,没有int 类型的属性。
在这里实现hashCode() 变得很困难,因为hashCode() 需要返回一个int。
以下是Record 类的示例。
public class Record{
String employeeName;
String employeeGroup;
Record(String name, String group){
employeeName= name;
employeeGroup = group;
}
public String getEmployeeName(){
return employeeName;
}
public String getEmployeeGroup(){
return employeeGroup;
}
@Override
public boolean equals(Object o){
if(o instanceof Record){
if (((Record) o).employeeGroup.equals(employeeGroup) &&
((Record) o).employeeName.equals(employeeName)){
return true;
}
}
return false;
}
@Override
public int hashCode() { //this should return a unique code
int hash = 3; //this could be anything, but I would chose a prime(e.g. 5, 7, 11 )
//again, the multiplier could be anything like 59,79,89, any prime
hash = 89 * hash + Objects.hashCode(this.employeeGroup);
return hash;
}
正如其他人之前建议的那样,该类需要同时覆盖 equals() 和 hashCode() 方法才能使用 HashSet。
现在,假设记录列表是allRecord(List<Record> allRecord)。
Set<Record> distinctRecords = new HashSet<>();
for(Record rc: allRecord){
distinctRecords.add(rc);
}
这只会将不同的记录添加到哈希集 distinctRecords。
希望这会有所帮助。
【讨论】:
public static List getUniqueValues(List input) {
return new ArrayList<>(new LinkedHashSet<>(incoming));
}
别忘了先实现你的equals方法
【讨论】:
如果你有一个某种对象(bean)的数组,你可以这样做:
List<aBean> gasList = createDuplicateGasBeans();
Set<aBean> uniqueGas = new HashSet<aBean>(gasList);
就像上面说的 Mathias Schwarz 一样,但是您必须为您的 aBean 提供 hashCode() 和 equals(Object obj) 方法,这可以在 Eclipse 中通过专用菜单“Generate hashCode() and equals()”轻松完成(在 bean 类中)。
Set 将评估覆盖的方法以区分等于对象。
【讨论】: