1) List

 저장된 요소들의 순서가 있고, 데이터에 중복이 가능하고 인덱스(index) 번호에 의해서 정렬된다.

  - 리스트는 컬렉션 인터페이스 중 하나이다.

  - 리스트는 2개의 종류로 나뉜다 (ArrayList, LinkedList)

  - 리스트는 크기 조절이 가능하다

  - 리스트는 초기 크기를 지정하지 않아도 된다.

  - 리스트의 삭제는 공간을 지우는 것이다.

 리스트(List)는 다음의 형식으로 사용한다.

import java.util.ArrayList;

List<자료형> 리스트명 = new ArrayList();

<>은 제네릭이라고 한다. jdk1.5부터 시행됐고, 1.5이전에는 제네릭이 없기 때문에 매 메소드마다 자료형을 캐스팅 해주었다.

 

 List의 주요 기능

구분			설명
List.add(value)		데이터를 리스트의 가장 마지막 인덱스에 추가한다.
List.add(index, value)	데이터를 지정한 인덱스에 값을 넣고 이후의 값을 한칸씩 뒤로 밀어준다.
List.set(index, value)	데이터를 지정한 인덱스 값을 치환하여 저장한다.
List.remove(index)	지정한 인덱스의 데이터 값을 삭제한다.
List.clear()		리스트의 전체 요소를 삭제한다.
List.get(index)		리스트의 인덱스 요소를 반환한다.
List.size()		리스트의 크기를 반환한다.

 

2) Set

저장된 요소들의 순서가 존재하지 않고, 중복된 데이터를 허용하지 않는 컬렉션 인터페이스이다. Set은 인덱스로 객체를 관리하지 않기 때문에, 데이터를 검색하기 위해서는 iterator() 메서드로 Iterator(반복자)를 생성하고 데이터를 가져와야한다.

 셋(Set)은 다음과 같은 형식으로 사용한다.

import java.util.Set;

Set<자료형> 셋명 = new HashSet<자료형>();

 Set은 다음과 같은 메소드를 지원한다.

구분			설명
Set.add(value)		데이터를 셋에 추가한다.
Set.contains(value)	셋에 해당 데이터가 존재하는지 반환한다.
Set.clear()		셋의 전체 요소를 삭제한다.
Set.iterator()		셋의 검색을 위한 반복자 생성.
Set.size()		셋의 크기를 반환한다.

3) Map

 맵은 키(Key)와 값(Value)을 하나의 데이터로 저장하는 특징을 가진다. 이를 통해 해싱(hashing)을 가능하게 하여 데이터를 검색하는데 뛰어난 성능을 보이는 인터페이스이다. 리스트나 배열처럼 순차적으로 해당 요소 값을 구하지 않고 key를 통해 value를 얻기 때문에, 저장의 순서가 유지하지 않는다. 또한, key의 값은 중복을 허용하지 않고, value의 값은 중복을 허용한다.

 Map은 다음과 같은 형식으로 사용한다.

import java.util.HashMap;
import java.util.Map;

Map<Key, Value> map = new HashMap();

 Map은 다음과 같은 메소드를 지원한다.

구분				설명
Map.put(key,value)		데이터를 키를 입력받아 맵에 추가한다.
Map.get(key)			맵에 해당 키와 일차하는 데이터를 반환한다.
Map.containsKey(key)		맵에 해당하는 키가 있는지 확인하고, 존재하면 해당 데이터를 반환한다.
Map.containsValue(value)	맵에 해당하는 데이터를 가진 키가 하나 이상 존재하는지 반환한다.
Map.remove(key value)		맵에 해당하는 키값의 데이터를 제거한다.
Map.clear()			맵의 전체 요소를 삭제한다.
Map.size()			맵의 크기를 반환한다.

'Java' 카테고리의 다른 글

16. Java, 제네릭(Generics)  (0) 2022.11.08
15. Java(컬렉션), 스택, 큐, ArrayDeque  (0) 2022.11.08
13. Java, 컬렉션(Collection)  (0) 2022.11.08
12. Java(API), 시간 다루기  (0) 2022.11.07
11. Java(기초), 예외 처리(Exception)  (0) 2022.11.07

 1) 컬렉션 프레임워크란?

 다수의 데이터를 다루기 위한 자료구조를 표현하고 사용하는 클래스의 집합. JCF(Java Collections Framework)는 이러한 데이터, 자료구조인 컬렉션과 이를 구현하는 클래스를 정의하는 인터페이스를 제공한다. 다음은 Java 컬렉션 프레임워크의 상속구조를 나타낸다.

 2) 컬렉션 인터페이스와 자료구조

 콜렉션(Collection)은 모든 자료구조가 구현(implement)하는 인터페이스이다. 

구분		설명
----------------------------------------------------------------------------------------
List		순서가 있는 데이터의 집합이며, 데이터의 중복을 허용한다
Set		순서를 유지하지 않는 데이터의 집합이며, 데이터의 중복을 허용하지 않는다.
Map		키(Key)와 값(Value)의 쌍우로 이루어진 데이터의 집합이다.
		순서는 유지하지 않으며, 키는 중복을 허용하지 않고, 값은 중복을 허용한다.
Stack		마지막에 넣은 데이터를 먼저 꺼내는 자료구조이다. LIFO를 따른다.
Queue		먼저 넣은 데이터를 먼저 꺼내는 자료구조이다. FIFO를 따른다.

 

- 컬렉션 인터페이스에는 컬렉션 클래스에 저장된 데이터를 읽고, 추가하고 삭제하는 등 데이터를 다루은데 기본적인 메소드를 정의한다.

 2주차가 시작되었고, 오전시간에는 새로운 주차의 발제가 있었다. 이제부터 본격적인 학습 주간이라고 한다. 학습 주간 동안 우리는 Java의 기초, Python의 기초, 그리고 자료구조와 알고리즘을 학습할 예정이다.

 나의 경우에는, 이미 C#을 학습한 경험이 있기 때문에, Java를 학습하기 어느정도 수월할 것이라고 예상했고, 오늘 하루동안 오늘 제공 받은 Java 강의를 들으면서 객체 지향 프로그래밍의 개념을 다시한번 숙지하는 시간을 가졌다.

 Java와 C#은 상당히 비슷한 구조를 가지면서, 다른듯한 언어다. 예를 들면, Java의 경우 JVM, C#의 경우 .Net Framework라는 가상머신 위에서 구동하게 되는데, 각각의 가상 머신들은 개발환경, 운영체제와 상관없이 프로그램의 구동을 보장한다. 즉, 둘의 개념은 비슷하다고 생각한다.

 또한, 스크립트에서 약간의 차이가 있었는데, C#과 다르게 Java는 퍼블릭 클래스를 선언할 때마다, 새로운 스크립트를 작성해야 했다. 파일의 분류가 상당히 힘들어 질것 같은 느낌이였다. C#의 경우 그냥 새로운 퍼블릭 클래스를 작성할 때, 밑에 쭉붙이고 나중에 분리해도 문제가 없었지만, Java의 경우 그런것이 안되더라.

 오전 오후 동안은 오랜만에, 객체지향 프로그래밍 언어를 공부를 했고, 내가 알고있던 것, 새로이 이해한 것을 대조해서 공부하는 시간을 가질 수 있었다. Java의 언어에 대한 기본적인 학습을 끝내는 것이 오늘 하루의 최종 목표가 되었다.

 아직, 강의의 절반 부분밖에 수강하지 못했지만, 오늘 남은 시간동안 나머지를 전부 수행 가능해 보인다. 이것도 C#을 학습하지 않았다면 어려웠지 않았을까 생각이 들었다. 최대한 빠르게 복습하고 알고리즘과 자료구조를 다시 복습하는 시간을 가져야 할 것같다.

 - 오늘의 목표: Java 강의를 완강하기

 - 내일의 목표: 알고리즘, 자료구조 강의 시작하기

 java에서 제공하는 클래스중 날짜, 시간 정보를 제공해주는 클래스가 존재한다. 크게 3가지 종류가 있는데 다음과 같다

구분		용도
---------------------------------------------------------------
LocalDate	날짜 정보만 필요할 때 사용
LocalTime	시간 정보만 필요할 때 사용
LocalDateTime	날짜 정보와 시간 정보 둘다 필요할 때 사용

(1) LocalDate

// 로컬 컴퓨터의 현재 날짜 정보를 저장한 LocalDate 객체를 리턴
LocalDate curDate = LocalDate.now(); // result : 2022-11-07;

// 파라미터로 주어진 날짜 정보를 저장한 LocalDate 객체를 리턴
LocalDate newDate = LocalDate.of(2022,11,06) // result : 2022-11-06

(2) LocalTime

// 로컬 컴퓨터의 현재 시간 정보를 저장한 LocalDate 객체를 리턴. 
LocalTime currentTime = LocalTime.now();	// reuslt : 18:57:29.670239400

// 파라미터로 주어진 시간 정보를 저장한 LocalTime 객체를 리턴.
LocalTime targetTime = LocalTime.of(22,50,55); 	// result : 22:50:55
// 끝에 4번째 매개변수는 nanoSecond 인데 선택 값이다 굳이 쓰지 않아도 된다.

(3) LocalDateTime

// 로컬 컴퓨터의 현재 날짜와 시간 정보
LocalDateTime currentDateTime = LocalDateTime.now();	// result : 2022-11-07T18:57:29.670239400

LocalDateTime targetDateTime = LocalDateTime.of(2019, 11, 12, 12, 32, 22);
// result : 2022-11-06T13:22:57
// 여기도 second,nanoSecond 매개변수는 필수가 아닌 선택입니다.

- 날짜 더하기

  LocalDateTime에서는 몇일 후, 몇년 후 등 코드에서 사용할만한 날짜가 있기때문에, 메소드를 활용하여 날짜를 더하거나 빼줄 수 있다. 사용할 수 있는 메소드는 다음과 같다.

method			description
--------------------------------------------------------------------------------------
plusYears()		년
minusYears()		년
plusMonths()		개월
minusMonths()		개월
plusWeeks()		주
minusWeeks()		주
plusDays()		날짜
minusDays()		날짜
plusHours()		시
minusHours()		시
plusMinutes()		분
minusMinutes()		분
plusSeconds()		초
minusSeconds()		초
plusNanos()		밀리초
minusNanos()		밀리초

 

(4) 날짜 표기형식 변경

 DateTimeFormmater 클래스를 활용해 다양한 표기형식을 표현할 수 있다. 만약 내가 원하는 형식이 있다면 임의의 형식을 다음 메소드를 통해 만들 수 있다

DateTimeFormatter newFormatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String myDate = newFormatter.format(LocalDate.now());
System.out.println(myDate); // result: 2022/11/07

 yyyy에는 년도, MM에는 월, dd에는 날짜를 대입해준다.

 (1) 예외 처리란?

 코드를 완성했다고 항상 프로그램이 성공적으로 작동하는 것은 아니다. 다양한 예외 상황이 발생할 수 있는데, 이것에 대응하기 위해 예외처리 코드가 필요하다. 즉, 예외의 발생으로 인해 프로그램의 비정상적인 종료를 막기위해, 또한, 개발자에게 알려 코드를 보완할 수 있도록 하기위해 예외 처리를 사용한다.

 자바는 상속을 이용해서 모든 예외를 표현한다. 모든 예외 클래스틑 Throwable의 자손 클래스다. Throwalbe 에는 크게 두종류의 자식 클래스가 있다. 

구분		설명
--------------------------------------------------------------------------------
Error		프로그램이 종료되어야 하는 심각한 문제를 표현한다. 
		대부분 컴퓨터나 JVM이 시스템적으로 동작할 수 없는 상황을 표현한다. 
Exception	프로그램이 종료되지 않지만, 예외나 문제상황을 표현하기 위해 사용한다.

 자바에는 미리 정의되어 있는 예외 클래스들이 있다. 기본적으로 이미 있는 것을 사용하되, Throwable 또는 그 하위 클래스를 상속받아 예외클래스를 정의할 수 있다.

예외처리 상속 구조

(2) 예외처리 형식

기본적으로 예외처리는 다음과 같은 형식으로 사용한다.

try {
    // 예외가 발생할 가능성이 있는 코드를 구현합니다.
} catch (FileNotFoundException e) {
    // FileNotFoundException이 발생했을 경우,이를 처리하기 위한 코드를 구현합니다.
} catch (IOException e) {
    // FileNotFoundException이 아닌 IOException이 발생했을 경우,이를 처리하기 위한 코드를 구현합니다.
} finally {
    // 예외의 발생여부에 관계없이 항상 수행되어야하는 코드를 구현합니다.
}

예시를 들면 다음과 같이 사용할수 있다.

class ArrayCalculation {

    int[] arr = { 0, 1, 2, 3, 4 };

    public int divide(int denominatorIndex, int numeratorIndex) {
        return arr[denominatorIndex] / arr[numeratorIndex];
    }
}

public class main {
    public static void main(String[] args) {
        ArrayCalculation arrayCalculation = new ArrayCalculation();

        System.out.println("2 / 1 = " + arrayCalculation.divide(2, 1));

        try{
            System.out.println(
                "1 / 0 = " + arrayCalculation.divide(1, 0)); // java.lang.ArithmeticException: "/ by zero"
        } catch (ArithmeticException e){
            System.out.println("잘못된 계산입니다. " + e.getMessage());
        }

        try{
        System.out.println("Try to divide using out of index element = "
                           + arrayCalculation.divide(5, 0)); // java.lang.ArrayIndexOutOfBoundsException: 5
        } catch (ArrayIndexOutOfBoundsException e){
            System.out.println(
                "잘못된 index 범위로 나누었습니다. 범위는 0부터"  +
                (arrayCalculation.arr.length - 1) +
                "까지입니다.");
        }
    }
}

 

위 코드의 결과

 

 (1) 추상 클래스(abstract class)

 - 하나 이상의 추상 메소드를 포함하는 클래스를 가리켜 추상 클래스(abstract class)라고 한다. 이러한 추상 클래스는 객체 지향 프로그래밍에서 중요한 특징인 다형성을 가지는 메소드의 집합을 정의한다. 추상 클래스는 다음과 같은 형식으로 선언한다.

abstract class 클래스이름{
	...
	abstract 반환타입 메소드이름();
    ...
}

 이러한 추상 클래스는 동작이 정의되어 있지 않은 추상 메소드를 포함하고 있으므로, 인스턴스를 생성할 수 없다. 즉, 추 상클래스는 먼저 상속을 통해 자식 클래스를 만들고, 만든 자식 클래스에서 추상 클래스의 모든 추상 메소드를 오버라이딩하고 나서야 자식 클래스의 인스턴스를 생성할 수 있게 된다.

 

 (2) 인터페이스(interface)

 자식 클래스가 여러 부모 클래스를 상속받을 수 있다면, 다양한 동작을 수행할 수 있다는 장점을 가지게 되지만, 다중 상속을 할 경우에 메소드 출처의 모호성 등 여러가지 문제가 발생할 수 있어서 자바에서는 클래스를 통한 다중 상속을 지원하지 않는다. 그러나, 다중 상속의 이점을 버릴 수 없기에, 자바에서는 인터페이스를 통한 다중 상속을 지원한다. 

 다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개역할까지 담당하는 일종의 추상클래스를 인터페이스라고한다. 인터페이스는 다음과 같이 선언한다.

접근제어자 interface 인터페이스이름 {
	public static final 타입 상수이름 = 값;
    ...
    public abstract 메소드이름(매개변수목록);
    ...
}

 -인터페이스의 구현

  인터페이스는 추상 클래스와 마찬가지고 자신이 직접 인스턴스를 생성할 수는 없다. 즉, 인터페이스가 포함하고 있는 추상메소드를 구현해 줄 클래스를 작성해야한다. 자바에서는 implements를 통해 인터페이스를 구현한다.

class 클래스이름 implements 인터페이스이름 { ... }

 (3) 인터페이스와 추상클래스의 비교

인터페이스
 - 구현하려는 객체 동작의 명세
 - 다중 상속 가능
 - implements를 이용하여 구현
 - 메소드 시그니처(이름, 파라미터, 리턴타입)에 대한 선언만 가능
 
추상클래스
 - 클래스를 상속받아 이용 및 확장을 위함
 - 다중 상속 불가능
 - extends를 이용하여 구현
 - 추상메소드에 대한 구현 가능

 - 접근 제어자란?

 멤버 변수/함수 혹은 클래스에 사용되며, 외부에서 접근을 제한하는 역할을 한다.

구분		설명
-----------------------------------
private		같은 클래스 내에서만 접근이 가능하다.
default		같은 패키지 내에서만 접근이 가능하다.
protected	같은 패키지내, 그리고 다른 패키지의 자식 클래스에서 접근이 가능하다.
public		접근 제한이 없다.

 

 - 상속(Inheritance)이란?

  쉽게 말해서, 부모 클래스(상위 클래스)와 자식 클래스(하위 클래스)가 있으며, 자식 클래스는 부모 클래스를 선택해서, 그 부모의 멤버를 상속받아 그래도 쓸 수 있게 된다. 즉, 상속은 이미 마련된 클래스를 재사용해서 만들 수 있기 때문에 효율적이게 코드를 관리할 수 있도록 한다. 상속을 하더라도 자식 클래스는 부모의 모든 것을 물려받는 것은 아니다

  - 부모 클래스의 private 접근 제한을 갖는 필드 및 메소드는 자식이 물려받을 수 없다.

  - 부모와 자식 클래스가 서로 다른 패키지에 있다면, 부모의 default 접근 제한을 갖는 필드 및 메소드도 자식이 물려받을 수 없다.

 

 - 클래스의 상속

  상속 받고자 하는 자식 클래스명 옆에 extends 키워드를 붙이고, 상속할 부모 클래스명을 적는다

public class Parent { ... }; // 부모 클래스
public class Child extends Parent { ... } // 자식 클래스

 - 부모 생성자의 호출: super(...);

 자바에서는 자식 객체를 생성하면, 부모 객체를 먼저 생성한 후, 자식 객체가 그 다음에 생성된다. 객체는 생성자 호출해야만 생성되는데, 일단 생성자는 '명시적인 생성자 선언'이 없다면, 컴파일러는 알아서 기본 생성자를 생성하여 호출한다. 그러나 자식 클래스에서 명시적 생성자 선언이 있다면, 자식 클래스 안의 생성자 선언 내부 맨 첫줄에 super(); 라고 생성하게 된다. 즉, super 키워드는 부모 클래스(객체)를 나타내는 것임을 기억하면 된다.

 

 - 오버로딩(Overloading)과 오버라이딩(Overridding) 

 (1)오버로딩(Overloading)

 오버 로딩은, 자바의 한 클래스 내에 이미 사용하려는 이름과 같은 이름을 가진 메소드가 있다고 하더라도, 매개변수의 개수나 타입이 다를때, 같은 이름을 사용해서 메소드를 정의할 수 있다. 즉, 같은 기능을 하지만, 매개 변수로 사용되는 데이터 타입이 달라도, 같은 이름을 사용하여 똑같은 기능을 할 수 있게 해준다. 단, 반환되는 값만 다르게 지정할 수 없다. 

 (2) 오버로딩을 사용하는 이유

  같은 기능을 하는 메소드를 하나의 이름으로 사용할 수 있다. 즉, println이라는 메소드는 인자값으로 int, double, boolean, String 등, 다양한 타입의 매개변수를 넣을 수 있지만, 콘솔창에 출력하는 기능을 수행한다. 이것은 같은 기능을 가진 메소드를 println이라는 하나의 이름으로 정의 한 것이다. 즉, 오버로딩의 대표적인 메소드라고 볼수 있다.

 

 (3) 오버라이딩(Overriding)

  부모 클래스로부터 상속받은 메소드를 자식 클래스에서 재정의 하는 것을 오버라이딩이라고 한다. 상속받은 메소드를 그대로 사용할 수 있지만, 자식 클래스에서 상황에 맞게 변경해야하는 경우, 오버라이딩 할 필요가 생긴다. 오버라이딩은 부모 클래스의 메소드를 재정의하는 것이므로, 자식 클래스에서는 오버라이딩 하고자 하는 메소드의 이름, 매개 변수, 리턴 값이 모두 같아야한다.

 

구분			Overriding			Overloading
---------------------------------------------------------------------------------------
접근 제어자		부모 클래스의 메소드의 		모든 접근제어자 사용가능
            		접근제어자보다 더 넓은 범위	
리턴형			동일해야 한다			달라도 된다
매소드명			동일해야 한다			달라도 된다
매개변수			동일해야 한다			달라도 된다
적용 범위		상속 관계			같은 클래스 내

+ Recent posts