[英]Get unique values from ArrayList in Java
我有一个包含许多记录的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()方法来识别重复项。
方法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
我希望我能正确理解您的问题:假设值的类型为String
,最有效的方法可能是转换为HashSet
并对其进行迭代:
ArrayList<String> values = ... //Your values
HashSet<String> uniqueValues = new HashSet<>(values);
for (String value : uniqueValues) {
... //Do something
}
你可以用它来制作一个独特的列表
ArrayList<String> listWithDuplicateValues = new ArrayList<>();
list.add("first");
list.add("first");
list.add("second");
ArrayList uniqueList = (ArrayList) listWithDuplicateValues.stream().distinct().collect(Collectors.toList());
这是直接的方法,无需诉诸自定义比较器或类似的东西:
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
否则效率较低,因此即使在需要排序时使用HashSet
通常更好,很少更糟。
ArrayList values = ... // your values
Set uniqueValues = new HashSet(values); //now unique
public static List getUniqueValues(List input) {
return new ArrayList<>(new LinkedHashSet<>(incoming));
}
不要忘记先实现你的 equals 方法
当我做同样的查询时,我很难根据我的情况调整解决方案,尽管之前的所有答案都有很好的见解。
当必须获取唯一对象列表而不是字符串时,这是一个解决方案。 比方说,有一个 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
。
现在,假设 Records 列表是allRecord
( List<Record> allRecord
)。
Set<Record> distinctRecords = new HashSet<>();
for(Record rc: allRecord){
distinctRecords.add(rc);
}
这只会将不同的记录添加到哈希集,distinctRecords。
希望这可以帮助。
如果您有某种对象(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 将评估覆盖的方法以区分 equals 对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.