从Java中的arraylist获取唯一值


81

我有一个ArrayList具有大量记录的记录,并且一列包含诸如CO2 CH4 SO2等的气体名称ArrayList。怎么做到呢?


4
我将更新标签。这是一个Java问题,我相信它与jsf和primefaces无关...
Mathias Schwarz

Answers:


133

您应该使用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()方法来标识重复项。


这意味着如果2个记录的名称相等,则将其视为相等(在HashSet的意义上)。
njzk2 2014年

@ njzk2-我认为这很明显,但是我想我可以进行编辑以明确指出这一点……
jahroy 2014年

尝试实现上述代码时出现错误: java: no suitable constructor found for HashSet。知道为什么会这样吗?
lordlabakdas

66

您可以使用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

11

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

ArrayList<String> values = ... //Your values
HashSet<String> uniqueValues = new HashSet<>(values);
for (String value : uniqueValues) {
   ... //Do something
}

6
ArrayList values = ... // your values
Set uniqueValues = new HashSet(values); //now unique

我现在从列表中获得了独特的元素,但是它是按自身进行排序的。但是我需要的数据不是按排序的顺序,那怎么办呢?
SDas 2012年

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可以直接排序的arraylistCollections.sort可以跳过,但是上面的方法TreeSet效率不高,因此HashSet即使需要排序,使用它通常更好,很少坏。


3

您可以使用它来使列表唯一

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

ArrayList uniqueList = (ArrayList) listWithDuplicateValues.stream().distinct().collect(Collectors.toList());

2

当我进行相同的查询时,尽管以前的所有答案都有很好的见识,但我很难调整自己的解决方案。

当必须获取唯一对象而不是字符串的列表时,这是一种解决方案。假设有一个Record对象的列表。Record类仅具有type的String属性,而没有type的属性inthashCode()由于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

现在,假设记录列表为allRecordList<Record> allRecord)。

Set<Record> distinctRecords = new HashSet<>();

for(Record rc: allRecord){
    distinctRecords.add(rc);
}

这只会将非重复记录添加到哈希集中,非重复记录。

希望这可以帮助。


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将评估重写的方法以区分等于对象。


1
  @SuppressWarnings({ "unchecked", "rawtypes" })
    public static List getUniqueValues(List input) {
    return new ArrayList<>(new HashSet<>(input));
    }

不要忘记实现您的equals方法

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.