94

I have an ArrayList with a number of records and one column contains gas names as CO2 CH4 SO2, etc. Now I want to retrieve different gas names(unique) only without repeatation from the ArrayList. How can it be done?

4

9 回答 9

149

您应该使用Set. ASet是一个不包含重复项的集合。

如果您有一个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()方法来识别重复项。

于 2012-11-17T09:11:39.420 回答
79

您可以使用Java 8 Stream API

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
于 2015-11-16T12:36:23.410 回答
12

我希望我能正确理解您的问题:假设值是 type String,最有效的方法可能是转换为 aHashSet并对其进行迭代:

ArrayList<String> values = ... //Your values
HashSet<String> uniqueValues = new HashSet<>(values);
for (String value : uniqueValues) {
   ... //Do something
}
于 2012-11-17T09:01:34.170 回答
6
ArrayList values = ... // your values
Set uniqueValues = new HashSet(values); //now unique
于 2012-11-17T11:37:32.427 回答
6

这是直接的方法,无需使用自定义比较器或类似的东西:

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

于 2012-11-17T09:16:51.470 回答
5

你可以用它来制作一个唯一的列表

ArrayList<String> listWithDuplicateValues = new ArrayList<>();
list.add("first");
list.add("first");
list.add("second");

ArrayList uniqueList = (ArrayList) listWithDuplicateValues.stream().distinct().collect(Collectors.toList());
于 2018-08-30T09:37:13.237 回答
2
    public static List getUniqueValues(List input) {
      return new ArrayList<>(new LinkedHashSet<>(incoming));
    }

不要忘记先实现你的 equals 方法

于 2018-07-24T10:58:56.117 回答
2

当我做同样的查询时,我很难根据我的情况调整解决方案,尽管之前的所有答案都有很好的见解。

当必须获取唯一对象列表而不是字符串时,这是一种解决方案。假设有一个 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);
}

这只会将不同的记录添加到 Hashset,distinctRecords。

希望这可以帮助。

于 2018-11-23T00:37:28.757 回答
1

如果您有某种对象(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 将评估覆盖的方法以区分等于对象。

于 2013-11-22T13:26:37.410 回答