ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JAVA] 리스트의 중복 요소 제거하기
    Java/Collection(컬렉션) 2024. 9. 27. 16:40
    반응형

    목차

       

      자바에서는 리스트의 중복 요소를 제거하는 여러 가지 방법이 있습니다. List, HashSet, Stream API, TreeSet, 그리고 LinkedHashSet을 사용하는 방법이 있습니다. 각 방법에 대해 자세히 살펴보겠습니다.

       

      1. List를 사용하여 중복 제거

      List를 사용하여 중복을 제거하려면 우선 새로운 리스트를 만들고, 반복문을 사용하여 중복되는 요소가 없는지 확인하면서 요소를 추가해야 합니다.
      List를 사용하여 중복을 제거
      /**
       * 리스트에서 중복 요소를 제거 (List 사용)
       *
       * @param list 중복 요소를 제거할 리스트
       * @param <T> 리스트 요소의 타입
       * @return 중복이 제거된 리스트
       */
      public <T> List<T> removeDuplicatesUsingList(List<T> list) {
        List<T> result = new ArrayList<>();
        for (T element : list) {
          if (!result.contains(element)) {
            result.add(element);
          }
        }
        return result;
      }
      단위테스트
      @DisplayName("removeDuplicatesUsingList: 정수 리스트에서 중복 제거")
      @Test
      void testRemoveDuplicatesUsingListInteger() {
      
        // Given
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 1, 2, 5);
      
        // When
        List<Integer> result = listRemoveDuplicates.removeDuplicatesUsingList(list);
      
        // Then
        List<Integer> expected = Arrays.asList(1, 2, 3, 4, 5);
        assertEquals(expected, result);
      }
      장점 :
      - 심플함 : 기본적인 자바 리스트를 사용합니다.
      단점 :
      - 성능 : contains 메서드는 리스트 크기가 커질수록 성능이 저하됩니다.
       

      2. HashSet을 사용하여 중복 제거

      HashSet을 사용하면 중복 요소가 자동으로 제거됩니다. HashSet은 중복을 허용하지 않기 때문에 쉽게 중복을 처리할 수 있습니다.
      HashSet을 사용하여 중복을 제거
      /**
       * 리스트에서 중복 요소를 제거 (HashSet 사용)
       *
       * @param list 중복 요소를 제거할 리스트
       * @param <T> 리스트 요소의 타입
       * @return 중복이 제거된 리스트
       */
      public <T> List<T> removeDuplicatesUsingSet(List<T> list) {
        return new ArrayList<>(new HashSet<>(list));
      }
      단위테스트 
      @DisplayName("removeDuplicatesUsingSet: 정수 리스트에서 중복 제거")
      @Test
      void testRemoveDuplicatesUsingSetInteger() {
      
        // Given
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 1, 2, 5);
      
        // When
        List<Integer> result = listRemoveDuplicates.removeDuplicatesUsingSet(list);
      
        // Then
        List<Integer> expected = Arrays.asList(1, 2, 3, 4, 5);
        assertEquals(expected, result);
      }
      장점 :
      - 효율성 : 해시 테이블을 기반으로 하기 때문에 성능이 좋습니다.
      단점 : 
      - 순서 유지 불가 : 원래 리스트의 순서가 유지되지 않습니다.
       

      3. Stream API를 사용하여 중복 제거

      스트림의 distinct() 메서드를 사용하여 중복을 제거할 수 있습니다.
      Stream API를 사용한 방법
      /**
       * Stream API를 사용하여 리스트에서 중복 요소를 제거
       *
       * @param list 중복 요소를 제거할 리스트
       * @param <T> 리스트 요소의 타입
       * @return 중복이 제거된 리스트
       */
      public <T> List<T> removeDuplicatesUsingStream(List<T> list) {
        return list.stream()
            .distinct()
            .collect(Collectors.toList());
      }
      단위테스트
      @DisplayName("removeDuplicatesUsingStream: 정수 리스트에서 중복 제거")
      @Test
      void testRemoveDuplicatesUsingStreamInteger() {
      
        // Given
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 1, 2, 5);
      
        // When
        List<Integer> result = listRemoveDuplicates.removeDuplicatesUsingStream(list);
      
        // Then
        List<Integer> expected = Arrays.asList(1, 2, 3, 4, 5);
        assertEquals(expected, result);
      }
      장점 :
      - 가독성 : 코드가 매우 간결하고 읽기 쉽습니다.
      단점 :
      - 성능 : 스트림은 약간의 성능 오버헤드를 수반하지만, 대부분의 경우 이는 무시할 수 있습니다.
       

      4. TreeSet을 사용하여 중복 제거

      TreeSet을 사용하면 중복 제거와 동시에 요소가 정렬됩니다. TreeSet은 NavigableSet의 구현체로, 요소가 정렬되어 저장됩니다.
      TreeSet을 사용한 방법
      /**
       * 리스트에서 중복 요소를 제거 (TreeSet 사용, 요소 정렬)
       *
       * @param list 중복 요소를 제거할 리스트
       * @param <T> 리스트 요소의 타입
       * @return 중복이 제거되고 정렬된 리스트
       */
      public <T> List<T> removeDuplicatesUsingTreeSet(List<T> list) {
        return new ArrayList<>(new TreeSet<>(list));
      }
      단위테스트
      @DisplayName("removeDuplicatesUsingTreeSet: 정수 리스트에서 중복 제거 및 정렬")
      @Test
      void testRemoveDuplicatesUsingTreeSetInteger() {
      
        // Given
        List<Integer> list = Arrays.asList(4, 3, 2, 1, 5, 4, 3, 2, 1);
      
        // When
        List<Integer> result = listRemoveDuplicates.removeDuplicatesUsingTreeSet(list);
      
        // Then
        List<Integer> expected = Arrays.asList(1, 2, 3, 4, 5);
        assertEquals(expected, result);
      }
      장점 :
      - 정렬 : 요소가 정렬됩니다.
      단점 :
      - 성능 : 요소가 정렬되면서 추가적인 연산 시간이 발생합니다.
       

      5. LinkedHashSet을 사용하여 중복 제거

      LinkedHashSet을 사용하면 중복을 제거하면서 삽입 순서를 유지할 수 있습니다.
      LinkedHashSet을 사용한 방법
      /**
       * 리스트에서 중복 요소를 제거 (LinkedHashSet 사용, 삽입 순서 유지)
       *
       * @param list 중복 요소를 제거할 리스트
       * @param <T> 리스트 요소의 타입
       * @return 중복이 제거되고 삽입 순서가 유지된 리스트
       */
      public <T> List<T> removeDuplicatesUsingLinkedHashSet(List<T> list) {
        return new ArrayList<>(new LinkedHashSet<>(list));
      }
      단위테스트
      @DisplayName("removeDuplicatesUsingLinkedHashSet: 정수 리스트에서 중복 제거 및 삽입 순서 유지")
      @Test
      void testRemoveDuplicatesUsingLinkedHashSetInteger() {
      
        // Given
        List<Integer> list = Arrays.asList(5, 4, 3, 2, 1, 5, 4, 3, 2, 1);
      
        // When
        List<Integer> result = listRemoveDuplicates.removeDuplicatesUsingLinkedHashSet(list);
      
        // Then
        List<Integer> expected = Arrays.asList(5, 4, 3, 2, 1);
        assertEquals(expected, result);
      }
      장점 :
      - 순서 유지 : 원래 리스트의 삽입 순서가 유지됩니다.
      단점 :
      - 성능 : LinkedHashSet은 일반적인 HashSet보다 성능이 낮을 수 있습니다.

       

      결론

      결론적으로, 자바에서 리스트의 중복을 제거해야 할 때, 사용 사례에 따라 다양한 방법을 선택할 수 있습니다.

      • 성능이 중요한 경우 : HashSet이나 TreeSet을 사용
      • 순서를 유지해야 하는 경우:  LinkedHashSet을 사용
      • 코드의 간결성이 중요한 경우: Stream API를 사용
       

      소스 코드는 Github Repository- https://github.com/tychejin1218/blog/tree/main/java-collection 프로젝트를 참조하세요.

      반응형

      'Java > Collection(컬렉션)' 카테고리의 다른 글

      [JAVA] 컬렉션 간의 변환 방법  (0) 2024.10.04
      [JAVA] 맵 검색하기  (0) 2024.10.04
      [JAVA] 리스트 회전하기  (0) 2024.09.27
      [JAVA] 리스트의 합 구하기  (0) 2024.09.27
      [JAVA] 리스트 검색하기  (0) 2024.09.27

      댓글

    Designed by Tistory.