[Java] chapter9

Ryong·2024년 1월 4일
0

Java

목록 보기
10/12
post-thumbnail

Generic

Java Generics(제네릭)은 컴파일 시간에 타입을 체크하고 형 안전성(type safety)을 제공하는 Java의 기능이다. Generics를 사용하면 컴파일러는 타입을 지정하지 않은 경우 경고를 발생시키며, 이를 통해 프로그램의 안전성을 높일 수 있다.

Generics의 기본 개념:

  1. 타입 매개변수(Type Parameter): 클래스, 메서드 또는 인터페이스를 정의할 때, 타입을 나타내는 변수. 대표적으로 E (Element), T (Type), K (Key), V (Value) 등이 사용.

  2. 제네릭 클래스(Generic Class): 타입 매개변수를 사용하여 클래스를 정의하는 것.

    public class Box<T> {
        private T content;
    
        public void setContent(T content) {
            this.content = content;
        }
    
        public T getContent() {
            return content;
        }
    }
  3. 제네릭 메서드(Generic Method): 타입 매개변수를 사용하여 메서드를 정의하는 것.

    public <T> T genericMethod(T value) {
        // 메서드 내용
        return value;
    }
  4. 와일드카드(Wildcard): ?를 사용하여 모든 타입을 나타낼 수 있는데, 이를 활용하여 다양한 타입에 대응할 수 있다.

    public void processList(List<?> list) {
        // 리스트를 처리하는 로직
    }

Generics의 장점:

  1. 안전성(Type Safety): 컴파일 시에 타입을 체크하기 때문에 런타임에 발생할 수 있는 타입 관련 오류를 사전에 방지.

  2. 재사용성(Reusability): 타입 매개변수를 이용하여 여러 타입에서 동일한 코드를 재사용.

  3. 표현력(Expressiveness): 코드의 가독성이 향상되며, 제네릭을 사용함으로써 불필요한 형변환 코드 감소.

Generics의 예제:

// 제네릭 클래스 예제
public class Box<T> {
    private T content;

    public void setContent(T content) {
        this.content = content;
    }

    public T getContent() {
        return content;
    }
}

// 제네릭 메서드 예제
public class GenericMethodExample {
    public <T> void printArray(T[] array) {
        for (T element : array) {
            System.out.print(element + " ");
        }
        System.out.println();
    }
}

// 와일드카드 예제
public class WildcardExample {
    public void processList(List<?> list) {
        for (Object element : list) {
            System.out.print(element + " ");
        }
        System.out.println();
    }
}

// Generics를 사용한 예제 코드
public class GenericsExample {
    public static void main(String[] args) {
        // 제네릭 클래스 사용
        Box<String> stringBox = new Box<>();
        stringBox.setContent("Hello, Generics!");
        System.out.println("Box Content: " + stringBox.getContent());

        // 제네릭 메서드 사용
        GenericMethodExample genericMethodExample = new GenericMethodExample();
        Integer[] intArray = {1, 2, 3, 4, 5};
        String[] stringArray = {"A", "B", "C", "D", "E"};

        System.out.print("Integer Array: ");
        genericMethodExample.printArray(intArray);

        System.out.print("String Array: ");
        genericMethodExample.printArray(stringArray);

        // 와일드카드 사용
        WildcardExample wildcardExample = new WildcardExample();
        List<Integer> integerList = Arrays.asList(1, 2, 3, 4);
        List<String> stringList = Arrays.asList("One", "Two", "Three", "Four");

        System.out.print("Integer List: ");
        wildcardExample.processList(integerList);

        System.out.print("String List: ");
        wildcardExample.processList(stringList);
    }
}

text

텍스트(Text)는 문자열(String)을 다루는데 사용. Java에서 문자열은 기본적으로 java.lang.String 클래스를 통해 표현되며, 텍스트 처리에는 문자열과 관련된 여러 클래스 및 메서드가 사용된다.

문자열(String) 클래스:

String 클래스는 Java에서 문자열을 표현하는데 주로 사용되며, 불변(Immutable)한 특성을 가지고 있다. 새로운 문자열을 생성하면 이전 문자열은 변경되지 않고 새로운 문자열이 생성된다.

// 문자열 생성
String text = "Hello, Java!";

문자열의 주요 메서드:

  1. length(): 문자열의 길이를 반환.

    int length = text.length(); // 13
  2. charAt(int index): 지정된 인덱스의 문자를 반환.

    char firstChar = text.charAt(0); // 'H'
  3. substring(int beginIndex), substring(int beginIndex, int endIndex): 부분 문자열을 반환.

    String subString1 = text.substring(7); // "Java!"
    String subString2 = text.substring(7, 11); // "Java"
  4. concat(String str): 문자열을 이어붙인다.

    String concatenated = text.concat(" Welcome!"); // "Hello, Java! Welcome!"
  5. indexOf(String str), indexOf(String str, int fromIndex): 지정된 문자열이 처음으로 나타나는 인덱스를 반환.

    int index = text.indexOf("Java"); // 7
  6. startsWith(String prefix), endsWith(String suffix): 주어진 접두사 또는 접미사로 시작하는지 또는 끝나는지 여부를 확인.

    boolean startsWithHello = text.startsWith("Hello"); // true
    boolean endsWithJava = text.endsWith("Java"); // false

StringBuilder 및 StringBuffer 클래스:

StringBuilderStringBuffer 클래스는 가변적인 문자열을 다루는데 사용됩니다. 이들은 문자열을 변경할 수 있는 메서드를 제공하며, 특히 문자열을 동적으로 변경해야 하는 경우에 유용합니다.

// StringBuilder를 사용한 문자열 변경
StringBuilder stringBuilder = new StringBuilder("Hello");
stringBuilder.append(", Java!"); // "Hello, Java!"

StringBuilder 및 StringBuffer의 주요 메서드:

  1. append(String str): 문자열을 뒤에 추가.

    StringBuilder builder = new StringBuilder("Hello");
    builder.append(", Java!"); // "Hello, Java!"
  2. insert(int offset, String str): 지정된 위치에 문자열을 삽입.

    StringBuilder builder = new StringBuilder("Hello");
    builder.insert(5, ", Java!"); // "Hello, Java!"
  3. delete(int start, int end): 지정된 범위의 문자열을 삭제.

    StringBuilder builder = new StringBuilder("Hello, Java!");
    builder.delete(7, 12); // "Hello!"
  4. reverse(): 문자열을 뒤집는다.

    StringBuilder builder = new StringBuilder("Hello");
    builder.reverse(); // "olleH"

StringTokenizer 클래스:

StringTokenizer 클래스는 문자열을 특정 구분자(delimiter)를 기준으로 토큰(token)으로 분리하는 데 사용.

StringTokenizer tokenizer = new StringTokenizer("Apple,Orange,Banana", ",");
while (tokenizer.hasMoreTokens()) {
    String token = tokenizer.nextToken();
    System.out.println(token);
}

정규 표현식(Regular Expression):

Java에서는 정규 표현식을 사용하여 문자열의 패턴을 검색하고 조작하는 데에 PatternMatcher 클래스를 제공.

import java.util.regex.*;

Pattern pattern = Pattern.compile("\\b\\d+\\b");
Matcher matcher = pattern.matcher("123 Java 456");

while (matcher.find()) {
    System.out.println(matcher.group()); // "123", "456"
}

I/O

Java I/O(Input/Output)는 Java에서 데이터의 입력과 출력을 다루는 매우 중요한 부분. Java I/O는 java.io 패키지에 포함되어 있으며, 데이터를 읽고 쓰는 다양한 클래스와 인터페이스를 제공.

I/O 스트림(Stream):

Java I/O에서 데이터는 스트림을 통해 입출력된다. 스트림은 데이터의 흐름을 나타내며, 입력 스트림(Input Stream)은 데이터를 읽어오는데 사용되고, 출력 스트림(Output Stream)은 데이터를 쓰는데 사용된다.

  1. 바이트 스트림(Byte Stream): 바이트 단위로 데이터를 처리하는 스트림. InputStreamOutputStream 클래스 계열이 여기에 속한다.

  2. 문자 스트림(Character Stream): 문자(char) 단위로 데이터를 처리하는 스트림. ReaderWriter 클래스 계열이 여기에 속한다.

바이트 스트림(Byte Stream):

InputStream과 OutputStream:

  • InputStream: 바이트 스트림의 최상위 클래스로, 입력 스트림을 나타낸다. read() 메서드를 통해 바이트를 읽어온다.

  • OutputStream: 바이트 스트림의 최상위 클래스로, 출력 스트림을 나타낸다. write() 메서드를 통해 바이트를 쓰기한다.

FileInputStream과 FileOutputStream:

  • FileInputStream: 파일로부터 데이터를 바이트 단위로 읽어오는 클래스.

  • FileOutputStream: 파일에 데이터를 바이트 단위로 쓰는 클래스.

try (FileInputStream inputStream = new FileInputStream("input.txt");
     FileOutputStream outputStream = new FileOutputStream("output.txt")) {
    int data;
    while ((data = inputStream.read()) != -1) {
        outputStream.write(data);
    }
} catch (IOException e) {
    e.printStackTrace();
}

문자 스트림(Character Stream):

Reader와 Writer:

  • Reader: 문자 스트림의 최상위 클래스로, 입력 스트림을 나타낸다. read() 메서드를 통해 문자를 읽어온다.

  • Writer: 문자 스트림의 최상위 클래스로, 출력 스트림을 나타낸다. write() 메서드를 통해 문자를 쓰기한다.

FileReader와 FileWriter:

  • FileReader: 파일로부터 데이터를 문자 단위로 읽어오는 클래스.

  • FileWriter: 파일에 데이터를 문자 단위로 쓰는 클래스.

try (FileReader reader = new FileReader("input.txt");
     FileWriter writer = new FileWriter("output.txt")) {
    int data;
    while ((data = reader.read()) != -1) {
        writer.write(data);
    }
} catch (IOException e) {
    e.printStackTrace();
}

보조 스트림(Decorator Stream):

보조 스트림은 다른 스트림을 감싸서 추가적인 기능을 제공하는 스트림. 여러 보조 스트림을 조합하여 사용할 수 있다.

BufferedReader와 BufferedWriter:

  • BufferedReader: 버퍼링을 제공하여 문자를 라인 단위로 효율적으로 읽어온다.

  • BufferedWriter: 버퍼링을 제공하여 문자를 라인 단위로 효율적으로 쓰기한다.

try (BufferedReader bufferedReader = new BufferedReader(new FileReader("input.txt"));
     BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter("output.txt"))) {
    String line;
    while ((line = bufferedReader.readLine()) != null) {
        bufferedWriter.write(line);
        bufferedWriter.newLine();  // 개행 문자 추가
    }
} catch (IOException e) {
    e.printStackTrace();
}

직렬화(Serialization)와 역직렬화(Deserialization):

직렬화는 객체를 바이트 스트림으로 변환하는 과정이며, 역직렬화는 바이트 스트림을 객체로 변환하는 과정. ObjectInputStreamObjectOutputStream을 사용.

import java.io.*;

class Person implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String toString() {
        return "Person{name='" + name + "', age=" + age + "}";
    }
}

public class SerializationExample {
    public static void main(String[] args) {
        try (ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("person.ser"));
             ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("person.ser"))) {

            // 직렬화
            Person person = new Person("John", 25);
            objectOutputStream.writeObject(person);

            // 역직렬화
            Person deserializedPerson = (Person) objectInputStream.readObject();
            System.out.println("Deserialized Person: " + desFileInputStream("person.ser"));
            Person deserializedPerson = (Person) objectInputStream.readObject();
            objectInputStream.close();

            System.out.println("Deserialized Person: " + deserializedPerson);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
profile
새로운 시작. 그리고 도약

0개의 댓글

Powered by GraphCDN, the GraphQL CDN