Computer >> 컴퓨터 >  >> 프로그래밍 >> Java

Java로 두 개의 ArrayList에서 공통 요소 찾는 방법 (retainAll 활용)

이 글에서는 Java를 사용해 두 개의 ArrayList에서 공통 요소를 찾는 방법을 알아봅니다. ArrayList 클래스는 AbstractList를 상속하고 List 인터페이스를 구현한 클래스로, 필요에 따라 크기가 자동으로 늘어나는 동적 배열(dynamic array)을 지원합니다.

ArrayList는 초기 크기를 지정하여 생성하며, 지정된 크기를 초과하면 컬렉션이 자동으로 확장됩니다. 반대로 요소를 삭제하면 배열 크기가 줄어들 수도 있습니다.

그럼 실제 예제를 통해 확인해 보겠습니다.

입력 및 출력 예시

입력값이 다음과 같다고 가정해 보겠습니다.

첫 번째 리스트: [Java, Scala, Shell, JavaScript]
두 번째 리스트: [Java, Python, Shell]

원하는 출력 결과는 다음과 같습니다.

두 리스트의 공통 요소: [Java, Shell]

알고리즘

Step 1 - 시작한다
Step 2 - input_list_1과 input_list_2라는 두 개의 ArrayList를 선언한다
Step 3 - 값을 정의한다
Step 4 - 내장 메서드인 .retainAll()을 사용하여 두 리스트의 공통 요소를 추출한다
Step 5 - 결과를 출력한다
Step 6 - 종료한다

예제 1: main 함수에서 모든 로직 처리하기

첫 번째 방식은 모든 연산을 하나의 'main' 함수 안에서 처리하는 방법입니다.

import java.util.ArrayList;
public class Demo {
   public static void main(String[] args){
      ArrayList<String> input_list_1 = new ArrayList<String>();
      input_list_1.add("Java");
      input_list_1.add("Scala");
      input_list_1.add("Shell");
      input_list_1.add("JavaScript");
      System.out.println("첫 번째 리스트: " + input_list_1);
      ArrayList<String> input_list_2 = new ArrayList<String>();
      input_list_2.add("Java");
      input_list_2.add("Python");
      input_list_2.add("Shell");
      System.out.println("두 번째 리스트: " + input_list_2);
      input_list_1.retainAll(input_list_2);
      System.out.println("\n두 리스트의 공통 요소: " + input_list_1);
  }
}

실행 결과

첫 번째 리스트: [Java, Scala, Shell, JavaScript]
두 번째 리스트: [Java, Python, Shell]

두 리스트의 공통 요소: [Java, Shell]

예제 2: 객체 지향 방식으로 함수 분리하기

두 번째 방식은 객체 지향 프로그래밍(OOP) 스타일에 맞게 연산 로직을 별도의 함수로 캡슐화하는 방법입니다. 코드의 재사용성과 가독성이 향상됩니다.

import java.util.ArrayList;
public class Demo {
   static void get_common_elements(ArrayList<String> input_list_1, ArrayList<String> input_list_2){
      input_list_1.retainAll(input_list_2);
      System.out.println("\n두 리스트의 공통 요소: " + input_list_1);
  }
   public static void main(String[] args){
      ArrayList<String> input_list_1 = new ArrayList<String>();
      input_list_1.add("Java");
      input_list_1.add("Scala");
      input_list_1.add("Shell");
      input_list_1.add("JavaScript");
      System.out.println("첫 번째 리스트: " + input_list_1);
      ArrayList<String> input_list_2 = new ArrayList<String>();
      input_list_2.add("Java");
      input_list_2.add("Python");
      input_list_2.add("Shell");
      System.out.println("두 번째 리스트: " + input_list_2);
      get_common_elements(input_list_1, input_list_2);
  }
}

실행 결과

첫 번째 리스트: [Java, Scala, Shell, JavaScript]
두 번째 리스트: [Java, Python, Shell]

두 리스트의 공통 요소: [Java, Shell]

핵심 포인트 정리

retainAll() 메서드는 Collection 인터페이스에 정의되어 있으며, 호출한 리스트에서 인자로 전달된 컬렉션에 포함된 요소만 남기고 나머지는 모두 제거합니다. 즉, 교집합(intersection)을 손쉽게 구할 수 있는 강력한 도구입니다.

단, retainAll()은 원본 리스트를 직접 수정하므로 원본 데이터를 유지해야 하는 경우에는 리스트를 미리 복사한 뒤 사용하는 것이 좋습니다. 예를 들어 new ArrayList<>(input_list_1)처럼 복사본을 만들어 적용하면 안전합니다.