Do it! 알고리즘 입문: 자바 편 (9)[책리뷰 & Book review]
본문 바로가기

컴퓨터공부/책리뷰 & book review

Do it! 알고리즘 입문: 자바 편 (9)[책리뷰 & Book review]

by Life & study 2024. 1. 31.
반응형

 

 

 

 Do it! 알고리즘 입문: 자바 편 (9)[책리뷰 & Book review]

빌더 패턴은 복잡한 객체를 생성하는 방법을 정의하는 클래스와 표현하는 방법을 정의하는 클래스를 별도로 분리하여, 서로 다른 표현이라도 이를 생성할 수 있는 동일한 절차를 제공하는 디자인 패턴입니다.

이 패턴은 생성해야 되는 객체가 Optional한 속성을 많이 가질 때 빛을 발휘합니다1.

아래는 빌더 패턴을 사용하는 자바 코드 예제입니다:

Java

public class Computer {
    private String HDD;
    private String RAM;

    private Computer(ComputerBuilder builder) {
        this.HDD = builder.HDD;
        this.RAM = builder.RAM;
    }

    public static class ComputerBuilder {
        private String HDD;
        private String RAM;

        public ComputerBuilder(String hdd, String ram) {
            this.HDD = hdd;
            this.RAM = ram;
        }

        public Computer build() {
            return new Computer(this);
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Computer comp = new Computer.ComputerBuilder("500 GB", "8 GB").build();
    }
}


AI가 생성한 코드입니다. 신중하게 검토하고 사용하세요. FAQ의 자세한 정보.
위 코드에서 Computer 클래스는 빌더 패턴을 사용하여 객체를 생성합니다.

 

ComputerBuilder는 내부 클래스로, Computer 객체를 생성하는 데 필요한 모든 매개변수를 받습니다

build 메서드는 최종적으로 Computer 객체를 생성하고 반환합니다1.

빌더 패턴은 복잡한 객체를 생성하는 과정을 단순화하고, 가독성을 높이는 데 도움을 주는 디자인 패턴입니다. 

특히 많은 수의 매개변수를 가진 객체를 생성할 때 유용하게 사용되며, 생성자에 넘겨주어야 하는 매개변수의 순서를 기억하지 않아도 되는 장점이 있습니다.

아래에 빌더 패턴을 사용하는 간단한 Java 코드 예제를 보여드리겠습니다.

java

public class Pizza {
    private String dough;
    private String topping;

    private Pizza(Builder builder) {
        this.dough = builder.dough;
        this.topping = builder.topping;
    }

    public static class Builder {
        private String dough;
        private String topping;

        public Builder dough(String dough) {
            this.dough = dough;
            return this;
        }

        public Builder topping(String topping) {
            this.topping = topping;
            return this;
        }

        public Pizza build() {
            return new Pizza(this);
        }
    }
}


위의 코드에서 Pizza 클래스는 Builder라는 내부 클래스를 가지고 있습니다.

 

Builder 클래스는 Pizza를 생성하기 위한 다양한 메소드를 제공하며, 이 메소드들은 모두 Builder 객체 자신을 반환하여 메소드 체이닝을 가능하게 합니다.

마지막으로 build 메소드를 호출하여 최종적인 Pizza 객체를 생성합니다.

이러한 빌더 패턴의 사용 예는 다음과 같습니다:

java

Pizza pizza = new Pizza.Builder()
                .dough("Thick")
                .topping("Mushroom")
                .build();


위의 코드에서는 Pizza 객체를 생성하기 위해 빌더 패턴을 사용하였습니다. 

dough 메소드와 topping 메소드를 호출하여 Pizza의 속성을 설정하고, 마지막에 build 메소드를 호출하여 Pizza 객체를 생성합니다.

Java에서 List와 ArrayList는 컬렉션 프레임워크의 일부

Java에서 List와 ArrayList는 컬렉션 프레임워크의 일부로, 여러 데이터를 저장하고 관리하는 데 사용됩니다.

 

이들의 주요 차이점은 다음과 같습니다:

List는 인터페이스이며, ArrayList는 List 인터페이스를 구현한 구체적인 클래스입니다.
List는 메서드의 선언만을 가지며, ArrayList는 이러한 메서드들의 구체적인 구현을 제공합니다.
아래에 List와 ArrayList를 사용하는 간단한 예제를 제공하겠습니다:

java

import java.util.List;
import java.util.ArrayList;

public class Main {
    public static void main(String[] args) {
        // List 인터페이스를 이용해 ArrayList 객체를 생성
        List<String> listInterface = new ArrayList<>();

        // ArrayList 객체를 직접 생성
        ArrayList<String> arrayList = new ArrayList<>();

        // List 인터페이스를 통해 정의된 메서드 사용
        listInterface.add("Apple");
        String fruitFromList = listInterface.get(0); // "Apple"

        // ArrayList에서 정의된 메서드 사용
        arrayList.add("Banana");
        String fruitFromArrayList = arrayList.get(0); // "Banana"
    }
}


위 코드에서 listInterface는 

List 인터페이스를 통해 ArrayList 객체를 생성하고 있습니다. 

반면에 arrayList는 직접 ArrayList 객체를 생성하고 있습니다.

 두 경우 모두 add와 get 같은 메서드를 사용할 수 있습니다.

하지만, ArrayList 클래스는 List 인터페이스에 없는 몇몇 메서드를 추가로 제공합니다. 

예를 들어, 

ensureCapacity 메서드는 ArrayList의 내부 배열의 크기를 미리 설정할 수 있게 해줍니다. 

이와 같은 메서드는 List 인터페이스를 통해 ArrayList 객체를 생성한 경우에는 사용할 수 없습니다.

따라서, 

어떤 메서드를 사용할 수 있는지는 List 인터페이스를 사용하여 객체를 생성했는지, 

아니면 ArrayList를 직접 사용하여 객체를 생성했는지에 따라 달라집니다. 

이와 같은 차이점을 이해하고 있으면, 더욱 효율적인 코드를 작성하는 데 도움이 될 것입니다.

 

 

 

 

 

 

 

Java에서 List와 ArrayList

 

Java에서 List와 ArrayList는 데이터를 순차적으로 저장하고 관리하는 데 사용되지만,

 그 세부적인 동작 방식과 사용 용도에는 차이가 있습니다.

List : List는 인터페이스로, 특정한 동작 방식이 아니라 '규칙'을 정의합니다. 

따라서 List를 사용하면, 그 구현체가 ArrayList일 수도 있고, LinkedList일 수도 있습니다.

 

 즉, List를 사용할 때는 내부적으로 어떤 데이터 구조를 사용하는지에 대해 크게 신경 쓰지 않고, 일관된 방식으로 데이터를 처리하고 싶을 때 사용합니다.

 

java
List<String> list = new ArrayList<>();
list.add("Apple");
ArrayList : ArrayList는 List 인터페이스를 구현한 구체 클래스로, 내부적으로 배열을 사용하여 데이터를 저장합니다. 이로 인해 인덱스를 이용한 데이터 접근이 빠르지만, 크기를 변경하는 작업은 비용이 많이 듭니다. ArrayList를 직접 사용하면, ArrayList만이 제공하는 메서드(예: trimToSize(), ensureCapacity() 등)를 사용할 수 있습니다.

 

java
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("Banana");
즉, List 타입을 사용하면, 구현체가 무엇이든 동일한 방식으로 코드를 작성할 수 있습니다. 이는 코드의 유연성을 높여주며, 나중에 다른 구현체로 변경해야 할 경우 코드 변경을 최소화할 수 있습니다.

반면에 ArrayList를 직접 사용하면 ArrayList만의 특별한 기능을 사용할 수 있지만, 다른 List 구현체로 변경하려면 코드를 많이 수정해야 할 수 있습니다.

따라서, 사용하려는 메서드와 성능 요구사항, 그리고 코드의 유연성 등을 고려하여 적절한 타입(List 또는 ArrayList)을 선택하면 됩니다.

 

 

 

 

 

 

 

 

 List list = new ArrayList<>();


java

import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // List 인터페이스를 이용해 ArrayList 객체를 생성
        List<String> list = new ArrayList<>();

        // ArrayList 객체를 직접 생성
        ArrayList<String> arrayList = new ArrayList<>();

        // List 인터페이스를 통해 정의된 메서드 사용
        list.add("Apple");
        String fruitFromList = list.get(0); // "Apple"

        // ArrayList에서 정의된 메서드 사용
        arrayList.add("Banana");
        String fruitFromArrayList = arrayList.get(0); // "Banana"
    }
}


위 코드에서 List<String> list = new ArrayList<>();

 부분에서는 List 인터페이스를 통해 ArrayList 객체를 생성하고 있습니다. 

 

이렇게 하면 List 인터페이스가 정의한 메서드만 사용할 수 있습니다.

 List 인터페이스에 정의된 메서드는 모든 List 구현체에서 공통적으로 사용할 수 있는 기본적인 메서드입니다.

반면에 ArrayList<String> arrayList = new ArrayList<>(); 부분에서는 ArrayList 객체를 직접 생성하고 있습니다.

 

 이렇게 하면 ArrayList 클래스가 추가로 제공하는 메서드를 사용할 수 있습니다. 예를 들어, ensureCapacity(int minCapacity)나 trimToSize()와 같은 메서드는 ArrayList 클래스에서만 사용할 수 있습니다.

따라서 List 인터페이스를 사용하면, 구현체가 무엇이든 동일한 방식으로 코드를 작성할 수 있습니다. 

이는 코드의 유연성을 높여주며, 나중에 다른 구현체로 변경해야 할 경우 코드 변경을 최소화할 수 있습니다.

반면에 ArrayList를 직접 사용하면 ArrayList만의 특별한 기능을 사용할 수 있지만, 다른 List 구현체로 변경하려면 코드를 많이 수정해야 할 수 있습니다.

따라서, 사용하려는 메서드와 성능 요구사항, 그리고 코드의 유연성 등을 고려하여 적절한 타입(List 또는 ArrayList)을 선택하면 됩니다.




 

 

 

 

 

List와 ArrayList의 차이점

 

 

List (인터페이스)
|
|---- ArrayList (클래스)
|       |
|       |---- 동적 배열
|       |---- 모든 유형의 객체를 저장할 수 있음
|       |---- 배열과 유형한 인터페이스 제공
|       |---- 요소의 추가, 제거, 접근이 유연함
|
|---- LinkedList (클래스)
|
|---- Stack (클래스)
|
|---- Queue (클래스)

 

List (interface)
|
|____ ArrayList (class)
|    |
|    |____ add()
|    |____ remove()
|    |____ get()
|    |
|____ LinkedList (class)
     |
     |____ add()
     |____ remove()
     |____ get()


List는 인터페이스로, ArrayList와 같은 구체적인 클래스를 구현하는 데 사용됩니다. 

List는 컬렉션 프레임워크의 일부로,

ArrayList뿐만 아니라 LinkedList, Stack, Queue 등 다양한 리스트 구현체를 제공합니다.

 

List를 사용하면 구체적인 구현체를 변경해도 코드를 변경할 필요가 없습니다.

ArrayList는 List 인터페이스를 구현한 클래스로, 동적 배열을 제공합니다. 

ArrayList는 배열과 리스트의 특징을 모두 가지고 있습니다. 

즉, ArrayList는 동적으로 크기가 변하면서도 배열처럼 인덱스를 통해 빠르게 요소에 접근할 수 있습니다.

 


 

ArrayList와 LinkedList는 List 인터페이스를 구현하는 클래스입니다. 

이들은 List 인터페이스에 정의된 메서드들을 실제로 어떻게 수행할지를 정의합니다. 

또한, 이들 클래스는 각각 내부적으로 데이터를 어떻게 저장하고 관리할지를 결정합니다. 

ArrayList는 내부적으로 배열을 사용하여 데이터를 관리하고, LinkedList는 연결 리스트를 사용합니다.

 


ArrayList는 객체를 저장하는 동적 배열입니다. 

배열과 유사한 인터페이스를 제공하며, 배열보다 더 유연하게 요소를 추가하거나 제거할 수 있습니다. 

또한, 필요에 따라 동적으로 크기를 확장할 수 있습니다.

간단하게 말하면,

 List는 "무엇"을 하는지를 정의하고, ArrayList는 "어떻게" 그것을 하는지를 정의합니다. 

이로 인해, List 인터페이스를 사용하면 구체적인 구현체를 변경하더라도 코드를 변경할 필요가 없습니다. 

이는 코드의 유연성을 높여주며, 나중에 다른 List 구현체로 변경해야 할 경우 코드 변경을 최소화할 수 있습니다.

 

 

 

 

반응형

댓글