[TIL-260212] 자바 기초: 내부 클래스, 스레드, 람다, 스트림

2026. 2. 17. 13:48·Java
이 글은 2026년 2월 12일에 작성된 글입니다.

내부 클래스

  • 클래스 내부에 선언한 클래스
  • 선언하는 위치나 예약어에 따라 크게 인스턴스 내부 클래스, 정적 내부 클래스, 지역 내부 클래스, 익명 내부 클래스로 나뉜다.

익명 내부 클래스

다른 내부 클래스는 많이 쓰이지는 않고 익명 내부 클래스가 주로 쓰인다.
익명 클래스는 클래스 이름 없이 선언하고 바로 생성하여 사용할 수 있는 클래스이다.

class Outer{
    Runnable getRunnable(int i){
        int num = 100;
        return new Runnable() { //익명 내부 클래스. Runnable 인터페이스 생성
            @Override
            public void run() {
            num = 200;   //에러 남
            i = 10; //에러 남
            System.out.println(i);
            System.out.println(num);
            }
        };
    }
    Runnable runner = new Runnable() { //익명 내부 클래스를 변수에 대입
        @Override
        public void run() {
            System.out.println("Runnable 이 구현된 익명 클래스 변수");
        }
    };
}

익명 내부 클래스의 호출

public class AnonymousInnerTest{
    public static void main(String[] args) {
        Outer out = new Outer();
        Runnable runner = out.getRunnable(10); 
        runner.run(); 
        out.runner.run();
    }
}

 


스레드

실행 중인 프로그램 내에서 또 다른 실행의 흐름을 형성하는 주체

(한 프로세스 내에 스레드가 2개라면 2개의 코드 실행 흐름이 있는 것)

예제: 비프음을 발생시키면서 동시에 "띵" 출력

  1. Runnable 인터페이스를 구현한 BeepTask 클래스 만듦
  2. 메인 메서드에서 BeepTask 객체를 매개변수로 새로운 thread를 만듦
  3. 새 thread를 start()하면 내부적으로 run() 메서드 실행됨
  4. 동시에 메인 thread도 실행됨
  5. 결과: 비프음 5번 들리면서, 동시에 “띵”이 5번 출력됨.
import java.awt.Toolkit;

// 작업 스레드를 실행할 수 있는 Runnable 객체를 이용
public class BeepTask implements Runnable{
    // run() 메서드를 구현
    public void run() {
        Toolkit toolkit= Toolkit.getDefaultToolkit();
        for(int i=0; i<5; i++) {
            toolkit.beep();
            try { Thread.sleep(500); } catch(Exception e) {}
        }
    }
}
public class BeepPrintExample {
    public static void main(String[] args) {
        Runnable beepTask= new BeepTask();
        Thread thread= new Thread(beepTask); // 스레드의 매개변수로 Runnable 객체가 들어감
        thread.start(); //beepTask

        for(int i=0; i<5; i++) {
            System.out.println("띵");
            try { Thread.sleep(500); } catch(Exception e) {}
        }
    }
}

람다

메서드에게 전달할 수 있는 익명 클래스를 함수로 단순화 시킨 것.

자바에서 제공하는 함수형 프로그래밍 방식을 람다식이라고 한다.

람다의 구성

  • 람다 파라미터: 메서드의 파라미터
  • 화살표: 람다의 파라미터 리스트와 바디를 구분함
  • 람다 바디: 람다의 반환값에 해당하는 표현식

람다식 문법

  • 매개변수 자료형 생략 가능
    `(x, y) -> return x + y;`
  • 매개변수가 하나인 경우 괄호 생략 가능
    `str -> {System.out.println(str);}`
  • 중괄호 안 구현 부분이 한 문장인 경우 중괄호 생략 가능
    `str -> System.out.println(str);`
  • 구현 부분이 return문 하나라면 중괄호와 return문 모두 생략 가능
    `(x, y) -> x + y`

함수형 인터페이스

  • 추상 메서드를 딱 하나만 가지는 인터페이스.
  • 람다식은 오직 하나의 메서드를 선언한 인터페이스를 구현할 수 있다.
  • 하나의 메서드를 구현하여 인터페이스형 변수에 대입하기 때문에 인터페이스는 두 개 이상의 함수를 가져서는 안된다.
  • @FunctionalInterface 어노테이션을 추가하면 실수로 다른 메서드를 추가한 경우 오류 메시지가 나타나 함수형 인터페이스임을 명시할 수 있다.
  • 람다식으로 메서드를 구현한 뒤 호출하면 시스템 내부에서는 익명 클래스가 생성되고 이를 통해 익명 객체가 생성된다.
@FunctionalInterface    // 람다식으로 구현한 인터페이스에 다른 메서드를 추가하지 않기 위해 사용
public interface MyNumber {
    int getMax(int num1, int num2);
}
public class TestMyNumber {
    public static void main(String[] args) {
        MyNumber max = (a,b) -> (a>=b)?a:b;  // 람다식을 인터페이스 자료형 max 변수에 대입
        System.out.println(max.getMax(10,20));  // 인터페이스 자료형 변수로 함수 호출

        // 내부적으로는 이렇게 익명 클래스가 생성되고 익명 객체가 생성됨
        MyNumber max2 = new MyNumber() {
            @Override
            public int getMax(int num1, int num2) {
                return (num1>=num2)? num1: num2;
            }
        };
        System.out.println(max2.getMax(10,20)); 
    }
}

함수형 프로그래밍

  1. 인터페이스를 구현한 람다식이 대입된 변수를 사용하여 람다식 구현부를 호출할 수 있다.
  2. 람다식을 변수에 대입하여 매개변수로 전달이 가능하다. 자료형은 인터페이스형이다.
  3. 함수의 반환형을 인터페이스형으로 하면 구현한 람다식 반환이 가능하다.

⇒ 함수의 구현부를 변수에 대입하고, 매개변수로 전달하고, 함수의 반환값으로 사용할 수 있다.

package practice;

interface PrintString{
    void showString(String str);
}

public class TestLambda{
    public static void main(String[] args) {
        // 1. 인터페이스를 구현한 람다식이 대입된 변수를 사용해 람다식 구현부 호출
        PrintString lambdaStr= s->System.out.println(s); 
        lambdaStr.showString("hello lambda_1");

        // 2. 메서드의 매개변수로 람다식 대입한 변수 전달
        showMyString(lambdaStr);

        // 3. 인터페이스 변수로 람다식을 반환받음
        PrintString reStr= returnString(); 
        reStr.showString("hello "); // 메소드 호출
    }

    // 2. 람다식 변수 전달받음
    public static void showMyString(PrintString p) {
        p.showString("hello lambda_2");
    }

    public static PrintString returnString() {
        PrintString str= s-> System.out.println(s+ "world");
        return str;  // 3. 람다식을 반환값으로 사용
        //return s->System.out.println(s + "world");
    }
}

 


스트림

여러 자료의 처리에 대한 기능을 구현해 놓은 클래스.

자바 8부터 추가되어 컬렉션(Collection) 형태로 구성된 데이터를 람다를 이용해 간결하고 직관적으로 처리할 수 있게 해준다.

for, while 등 이용하던 기존의 loop를 대체할 수 있다.

스트림 연산

  • 중간연산
    • filter() : 특정 조건을 만족하는 요소만 추출
      sList.stream().filter(s->s.length()>=5).forEach(s->System.out.println(s));​
    • map() : 요소들을 특정한 형태로 변환 
      // 고객 리스트에서 고객의 이름만 출력하고 싶을 때
      customerList.stream().map(c->c.getName()).forEach(s->System.out.println(s));
      • mapToInt() : 요소들을 int 타입의 기본형 특화 스트림인 IntStream으로 변환
    • distinct() :중복된 요소 제거
      List<Integer> numbers = Arrays.asList(1, 2, 3, 2, 1, 4, 5, 4);
      
      // 중복 제거 후 리스트로 변환
      List<Integer> distinctNumbers = numbers.stream().distinct().collect(Collectors.toList());
      // 결과: [1, 2, 3, 4, 5]​
       
    • sorted() : 요소들을 오름차순으로 정렬
      (내림차순 하려면 파라미터로 Comparator.reverseOrder() 메서드를 넣음)
      sList.stream().sorted().forEach(s->System.out.print(s+" "));
       
  •  최종연산
    • forEach() : 요소를 하나씩 꺼내는 기능
      sList.stream().filter(s->s.length()>=5).forEach(s->System.out.println(s));​
       
    • sum() : 배열 요소의 합계를 구해서 해당 원시 타입으로 반환
    • count() : 배열 요소의 개수를 long으로 반환
    • average() : 배열 요소의 평균을 구해서 OptionalDouble로 반환
    • max(), min() : 배열 요소의 최댓값, 최솟값을 Optional로 반환
      int arr[] = {1,2,3,4,5};
      int sumVal = Arrays.stream(arr).sum();
      int count = (int) Arrays.stream(arr).count();
      double average = Arrays.stream(arr).average().getAsDouble();
      int max = Arrays.stream(arr).max().getAsInt();
      int min = Arrays.stream(arr).min().getAsInt();​
    • reduce() : 요소를 하나씩 소모하면서 프로그래머가 직접 작성하는 기능
      // 함수 정의
      T reduce(T identify, BinaryOperator<T> accumulator) // 매개변수: 초깃값, 수행해야 할 기능
      
      // 모든 요소의 합을 구함
      Arrays.stream(arr).reduce(0, (a,b)->a+b));
       
    •  collect() : 요소들을 List, Set, Map 등 다른 종류의 결과로 반환할 때 사용
      ArrayList<String> members = new ArrayList<>();
      members.add("Kim");
      members.add("Lee");
      members.add("Park");
      // Set로 변환
      Set<String> collectSet = members.stream().collect(Collectors.toSet());
      System.out.println(collectSet);​
       

스트림 특징

  • 자료의 대상과 관계없이 동일한 연산을 수행한다.
  • 한 번 생성하고 사용한 스트림은 재사용할 수 없다.
  • 스트림의 연산은 기존 자료를 변경하지 않는다.
  • 스트림의 연산은 중간 연산과 최종 연산이 있다.

 


❕느낀점

이제 자바의 대부분의 기초 문법을 다 배우게 되었다. 물론 아직 입출력에 대해서는 배우지 못했지만 그 부분은 알고리즘 공부하면서 알아가면 될 것 같다.

스트림은 오랜만에 들어도 어렵다. 눈으로 보면 이해가 되는데 막상 스스로 코드를 작성하려 하면 오류없이 한번에 작성하기는 어려울 것 같다. 스트림 연습도 많이 해야겠다.

사실 현업에서 이런 스트림이나 람다는 많이 안쓴다고 들어서.. 그 점은 감안하고 기본에 최대한 충실하되 알아두고 써먹을 수 있을 정도로는 공부해야겠다.

 

이제 곧.. 스프링..... 파이팅...

'Java' 카테고리의 다른 글

[TIL-260309] Servlet & JSP 입문: JSP 실습, Servlet 기초  (0) 2026.03.10
[TIL-260306] Servlet & JSP 입문: 자바와 웹, 웹 애플리케이션, HTTP  (0) 2026.03.08
[TIL-260211] 자바 기초: 예외처리와 제네릭, 컬렉션 프레임워크  (0) 2026.02.17
[TIL-260210] 자바 기초: 인터페이스  (0) 2026.02.17
[TIL-260209] 자바 기초: static, 상속, 추상 클래스  (0) 2026.02.17
'Java' 카테고리의 다른 글
  • [TIL-260309] Servlet & JSP 입문: JSP 실습, Servlet 기초
  • [TIL-260306] Servlet & JSP 입문: 자바와 웹, 웹 애플리케이션, HTTP
  • [TIL-260211] 자바 기초: 예외처리와 제네릭, 컬렉션 프레임워크
  • [TIL-260210] 자바 기초: 인터페이스
hee-on
hee-on
작은 기록을 모아 꾸준히 성장해 나가는 개발 기록 공간입니다💻
  • hee-on
    희온의 dev log
    hee-on
  • 전체
    오늘
    어제
    • 전체 글 (46)
      • About (2)
      • Java (15)
      • Spring (4)
      • Spring Boot (2)
      • Front-end (6)
      • 알고리즘 (6)
        • Do it 알고리즘 코딩테스트 (자바편) (4)
      • DB (7)
      • Git (1)
      • 개발 지식 (2)
      • 일상 || 잡담 (1)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    Servlet
    소개
    JavaScript
    SpringBoot
    백준
    안티그래비티
    백엔드
    취준
    JSP
    MVC
    til
    코테
    알고리즘
    깃허브 코파일럿
    Java
    react
    Spring
    SQL
    개발자
    db
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
hee-on
[TIL-260212] 자바 기초: 내부 클래스, 스레드, 람다, 스트림
상단으로

티스토리툴바