[java] Java의 arraylist에서 고유 값 가져 오기

나는 ArrayList많은 레코드를 가지고 있고 하나의 열에는 CO2 CH4 SO2 등의 가스 이름이 포함되어 있습니다 ArrayList. 이제. 어떻게 할 수 있습니까?



답변

당신은을 사용한다 Set. A Set는 중복 항목이없는 모음 입니다.

당신이있는 경우 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 8 Stream API를 사용할 수 있습니다 .

고유 한 메서드 는 스트림을 필터링하고 고유 한 값 (기본적으로 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하면 가장 효율적인 방법은 a로 변환 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직접 정렬 된 배열 목록이 제공되며 위의 내용 Collections.sort은 건너 뛸 수 있지만 TreeSet그렇지 않으면 효율성이 떨어 지므로 HashSet정렬이 필요할 때도 사용하는 것이 더 좋고 드물게 나쁩니다 .


답변

목록을 고유하게 만드는 데 사용할 수 있습니다.

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);
}

이것은 Hashset, distinctRecords에 고유 한 레코드 만 추가합니다.

도움이 되었기를 바랍니다.