Java/배열

[Java]배열에서 중복 제거하는 방법

DevStory 2022. 5. 7.

이번 포스팅은 배열에서 중복 요소를 제거하는 방법을 소개합니다.


LinkedHashSet 클래스

LinkedHashSet 클래스는 배열에서 중복 요소를 제거하는 가장 좋은 방법입니다. LinkedHashSet 클래스가 중복 제거에 좋은 이유는 두 가지 특징 때문입니다. 첫 번째 특징은 중복 요소를 제거합니다. 두 번째 특징은 순서를 유지하기 때문입니다. 

 

다음은 LinkedHashSet 클래스 예제입니다.

String[] strArray = new String[] {"B", "B", "C", "C", "A", "A", "A"};

// 배열을 LinkedHashSet으로 변환합니다.
LinkedHashSet<String> linkedHashSet = 
  new LinkedHashSet<>( Arrays.asList(strArray) );

// LinkedHashSet을 배열로 변환홥니다.
String[] strArrayWithoutDuplicates = 
  linkedHashSet.toArray(new String[] {});

System.out.println( Arrays.toString(strArrayWithoutDuplicates) );

실행 결과

[B, C, A]

Arrays 클래스의 asList() 메서드를 호출하여 배열을 List 객체로 변환 후 LinkedHasSet 생성자에 전달합니다. 다음으로 LinkedHasSet 클래스의 객체를 문자열 배열로 변환합니다. 중복 요소가 제거된 것을 확인할 수 있습니다.


Stream API 시용

Java 1.8 이상인 경우 Stream API의 distinct() 메서드를 사용할 수 있습니다. distinct() 메서드는 중복 요소가 존재하지 않은 데이터를 반환합니다.

String[] strArray = new String[] {"B", "B", "C", "C", "A", "A", "A"};

List<String> liWithoutDuplicate = Arrays.asList(strArray)
        .stream()
        .distinct()
        .collect(Collectors.toList());

System.out.println(liWithoutDuplicate);

실행 결과

[B, C, A]

임시 배열의 문제점

구글링 하면 임시 배열을 활용하거나 Arrays 클래스의 sort() 메서드 호출 후 중복 요소를 제거하는 방법을 찾을 수 있습니다. 이 방법은 한 가지 문제점이 존재하는데 원시 타입(Primitive Type)인 경우 null이 없으며, 래퍼 클래스(Wrapper Class)인 경우 null이 추가됩니다.

 

다음은 원시 타입인 int형 배열에서 임시 배열을 사용하여 중복 요소를 제거하는 예제입니다.

public class Main{
  public static int removeDuplicateElements(int arr[], int n){
    if (n == 0 || n == 1){
      return n;
    }
    
    int[] temp = new int[n];
    
    int j = 0;
    
    for (int i=0; i<n-1; i++){
      if (arr[i] != arr[i+1]){
        temp[j++] = arr[i];
      }
    }
    
    temp[j++] = arr[n-1];
    
    for (int i=0; i<j; i++){
      arr[i] = temp[i];
    }
    return j;
  }
  
  public static void main (String[] args) {
    int[] intArr = new int[] {10, 10, 20, 20, 20, 30, 30};
    int n = intArr.length;

    n = removeDuplicateElements(intArr, n);

    for (int i=0; i<n; i++)
      System.out.print(intArr[i] + " ");
  }
}

실행 결과

10 20 30

 

다음은 래퍼 클래스인 Integer 배열에서 임시 배열을 사용하여 중복 요소를 제거하는 예제입니다.

public class Main{
  public static int removeDuplicateElements(Integer arr[], int n){
    if (n==0 || n==1){
      return n;
    }
    
    Integer[] temp = new Integer[n];
    
    int j = 0;
    
    for (int i=0; i<n-1; i++){
      if (arr[i] != arr[i+1]){
        temp[j++] = arr[i];
      }
    }
    
    temp[j++] = arr[n-1];
    
    for (int i=0; i<j; i++){
      arr[i] = temp[i];
    }
    return j;
  }
  
  public static void main (String[] args) {
    Integer[] intArr = new Integer[] {10, 10, 20, 20, 20, 30, 30};
    int n = intArr.length;

    n = removeDuplicateElements(intArr, n);

    for (int i=0; i<n; i++)
      System.out.print(intArr[i] + " ");
  }
}

실행 결과

10 20 null 30

원시 타입인 int형 배열은 null이 존재하지 않으며, 래퍼 클래스인 Integer 배열은 null이 존재합니다. 원시 타입과 래퍼 클래스의 차이점을 정확하게 모르면 배열에 null이 추가되는 문제가 발생하므로 임시 배열을 사용하여 중복 요소를 제거하는 방법은 권장하지 않습니다.

반응형

댓글