주요 참조 : http://www.tcpschool.com/
자바에서 컬렉션 프레임워크(collection framework)란 다수의 데이터를 쉽고 효과적으로 처리할 수 있는 표준화된 방법을 제공하는 클래스의 집합을 의미합니다
즉, 데이터를 저장하는 자료 구조와 데이터를 처리하는 알고리즘을 구조화하여 클래스로 구현해 놓은 것입니다.
이러한 컬렉션 프레임워크는 자바의 인터페이스(interface)를 사용하여 구현됩니다.
자식 클래스가 여러 부모 클래스를 상속받을 수 있다면, 다양한 동작을 수행할 수 있다는 장점을 가지게 될 것입니다.
하지만 클래스를 이용하여 다중 상속을 할 경우 메소드 출처의 모호성 등 여러 가지 문제가 발생할 수 있어 자바에서는 클래스를 통한 다중 상속은 지원하지 않습니다.
하지만 다중 상속의 이점을 버릴 수는 없기에 자바에서는 인터페이스라는 것을 통해 다중 상속을 지원하고 있습니다.
인터페이스(interface)란 다른 클래스를 작성할 때 기본이 되는 틀을 제공하면서, 다른 클래스 사이의 중간 매개 역할까지 담당하는 일종의 추상 클래스를 의미합니다.
자바에서 추상 클래스는 추상 메소드뿐만 아니라 생성자, 필드, 일반 메소드도 포함할 수 있습니다.
하지만 인터페이스(interface)는 오로지 추상 메소드와 상수만을 포함할 수 있습니다.
List 인터페이스
Set 인터페이스
Map 인터페이스
이 중에서 List와 Set 인터페이스는 모두 Collection 인터페이스를 상속받지만, 구조상의 차이로 인해 Map 인터페이스는 별도로 정의됩니다.
따라서 List 인터페이스와 Set 인터페이스의 공통된 부분을 Collection 인터페이스에서 정의하고 있습니다.
List 인터페이스는 순서가 있는 데이터의 집합으로, 데이터의 중복을 허용함.
List 인터페이스를 이용하여 구현된 클래스에는 Vector, ArrayList, LinkedList, Stack, Queue 등이 있음.
ArrayList 클래스는 가장 많이 사용되는 컬렉션 클래스 중 하나입니다.
JDK 1.2부터 제공된 ArrayList 클래스는 내부적으로 배열을 이용하여 요소를 저장합니다.
ArrayList 클래스는 배열을 이용하기 때문에 인덱스를 이용해 배열 요소에 빠르게 접근할 수 있습니다.
하지만 배열은 크기를 변경할 수 없는 인스턴스이므로, 크기를 늘리기 위해서는 새로운 배열을 생성하고 기존의 요소들을 옮겨야 하는 복잡한 과정을 거쳐야 합니다.
물론 이 과정은 자동으로 수행되지만, 요소의 추가 및 삭제 작업에 걸리는 시간이 매우 길어지는 단점을 가지게 됩니다.
===> ArrayList란 가장 많이 사용되는 인터페이스 중의 하나로, 배열을 이용하기 떄문에 인덱스를 이용하여 배열 요소에 빠르게 접근 가능하지만 배열의 크기를 변경할 수 없어 배열 크기 수정에 부적절하다.
LinkedList 클래스는 ArrayList 클래스가 배열을 이용하여 요소를 저장함으로써 발생하는 단점을 극복하기 위해 고안되었습니다.
JDK 1.2부터 제공된 LinkedList 클래스는 내부적으로 연결 리스트(linked list)를 이용하여 요소를 저장합니다.
배열은 저장된 요소가 순차적으로 저장됩니다.
하지만 연결 리스트는 저장된 요소가 비순차적으로 분포되며, 이러한 요소들 사이를 링크(link)로 연결하여 구성합니다.
다음 요소를 가리키는 참조만을 가지는 연결 리스트를 단일 연결 리스트(singly linked list)라고 합니다.
이러한 단일 연결 리스트는 요소의 저장과 삭제 작업이 다음 요소를 가리키는 참조만 변경하면 되므로, 아주 빠르게 처리될 수 있습니다.
하지만 단일 연결 리스트는 현재 요소에서 이전 요소로 접근하기가 매우 어렵습니다.
따라서 이전 요소를 가리키는 참조도 가지는 이중 연결 리스트(doubly linked list)가 좀 더 많이 사용됩니다.
===> LinkedList는 데이터와 함께 다음 요소를 가리키는 참조값을 가지는 연결 리스트 형태이다. 배열과는 다르게 저장된 요소를 순차적으로 저장하지는 않는다.
Set 인터페이스는 순서가 없는 데이터의 집합으로, 데이터의 중복을 허용하지 않음.
Set 인터페이스를 이용하여 구현된 클래스에는 HashSet, TreeSet 등이 있음.
HashSet 클래스는 Set 컬렉션 클래스에서 가장 많이 사용되는 클래스 중 하나입니다.
JDK 1.2부터 제공된 HashSet 클래스는 해시 알고리즘(hash algorithm)을 사용하여 검색 속도가 매우 빠릅니다.
이러한 HashSet 클래스는 내부적으로 HashMap 인스턴스를 이용하여 요소를 저장합니다.
HashSet 클래스는 Set 인터페이스를 구현하므로, 요소를 순서에 상관없이 저장하고 중복된 값은 저장하지 않습니다.
TreeSet 클래스는 데이터가 정렬된 상태로 저장되는 이진 검색 트리(binary search tree)의 형태로 요소를 저장합니다.
이진 검색 트리는 데이터를 추가하거나 제거하는 등의 기본 동작 시간이 매우 빠릅니다.
JDK 1.2부터 제공되는 TreeSet 클래스는 NavigableSet 인터페이스를 기존의 이진 검색 트리의 성능을 향상시킨 레드-블랙 트리(Red-Black tree)로 구현합니다.
TreeSet 클래스는 Set 인터페이스를 구현하므로, 요소를 순서에 상관없이 저장하고 중복된 값은 저장하지 않습니다.
Map 인터페이스는 키와 값의 한 쌍으로 이루어지는 데이터의 집합으로, 순서가 없음.
이때 키는 중복을 허용하지 않지만, 값은 중복될 수 있음.
Map 인터페이스를 이용하여 구현된 클래스에는 HashMap, TreeMap, Hashtable, Properties 등이 있음.
HashMap 클래스는 Map 컬렉션 클래스에서 가장 많이 사용되는 클래스 중 하나입니다.
JDK 1.2부터 제공된 HashMap 클래스는 해시 알고리즘(hash algorithm)을 사용하여 검색 속도가 매우 빠릅니다.
HashMap 클래스는 Map 인터페이스를 구현하므로, 중복된 키로는 값을 저장할 수 없습니다.
하지만 같은 값을 다른 키로 저장하는 것은 가능합니다.
===> HashMap은 Map컬렉션 클래스에서 가장 대표적이고 많이 사용된다. 검색 속도가 매우 빠르다는 장점이 있다.
TreeMap 클래스는 키와 값을 한 쌍으로 하는 데이터를 이진 검색 트리(binary search tree)의 형태로 저장합니다.
이진 검색 트리는 데이터를 추가하거나 제거하는 등의 기본 동작 시간이 매우 빠릅니다.
JDK 1.2부터 제공된 TreeMap 클래스는 NavigableMap 인터페이스를 기존의 이진 검색 트리의 성능을 향상시킨 레드-블랙 트리(Red-Black tree)로 구현합니다.
이 컬렉션 프레임워크를 구성하는 클래스들이
모두 제네릭 형태로 선언되어있음을 의미함
컬렉션 인터페이스에서 List나 Set인터페이스의 많은 부분을 정의하고 두 인터페이스가 이것을 상속받아 이용함.
Java는 객체지향을 특징으로 하는 언어이다.
객체지향 프로그래밍(Object-Oriented Programming)이란 프로그램을 설계하는 개념이자 방법론이다.
줄여서 OOP라 부르며, 단어 뜻 그대로 프로그램(실제세계)를 객체(사물)라는 기본 단위로 나누고 이 객체들간의 상호작용을 기본개념으로 한다.
객체지향 프로그래밍(OOP)은 프로그램을 유연하고 변경하기 쉽게 만들기 때문에 재사용성이 용이하여 대규모 프로젝트에서 많이 사용되는 방법론이다. 프로그램 개발과 유지보수가 용이하다는 점이 가장 큰 장점으로 꼽힌다.
객체지향에서 추상화란 객체에서 공통된 속성과 행위를 추출하는 것을 의미한다.
예를들어, 게임 프로그램을 개발하며 캐릭터가 소지하는 다양한 무기들이 있다. 칼, 삽, 곡갱이, 총, 활 등 여러가지 무기들이 존재하는데, 이들의 기능적인 내용은 다르지만 공통적인 속성과 행위를 개념으로 무기라는 클래스를 정의할 수 있다.
이렇듯 추상화는 다른 객체들과 구분되는 핵심적인 부분에 집중하여, 복잡도를 관리할 수 있게 해준다.
캡슐화는 연관있는 변수와 메소드를 묶어주는 작업을 말한다.
접근 제어 지시자[public, private, protected]를 통해 외부로부터의 접근을 제한하여 객체내에서만 접근이 가능하도록 해준며, 이를 정보은닉이라 한다.
외부의 클래스 혹은 모듈에 의존적인 프로그램의 경우 변경이나 오류에 취약해지는데, 정보은닉을 통해 이러한 결합도를 낮추며 응집도를 높여준다.
클래스 개념이 도입되면서 상속을 통해 부모클래스의 속성과 기능을 이어받아(상속받아) 사용하는 것을 말한다.
프로그램을 개발하다보면 중복되는 속성과 기능을 개발해야 하는 일이 발생되는데 상속을 사용한다면 중복되는 기능을 반복하여 작업하지 않고 작업을 할 수 있게 해준다.
자식클래스는 상속을 통해 부모클래스의 속성과 기능을 물려받는다.
또한, 다형성을 통해 변경이 필요한 부분을 변경하여 사용할 수 있다.
다형성이란 프로그래밍 언어의 자료형 체계의 성질을 나타내는 것으로, 동일한 변수, 함수명 등이 다양한 방법으로 기능하는 것을 말하며
오버라이딩(Overriding), 오버로딩(Overloading)이란 형태로 제공된다.
오버로딩 : 같은 이름의 메서드 여러개를 가지면서 매개변수의 유형과 개수가 다르도록 하는 기술
출처: https://private.tistory.com/25 [오토봇팩토리:티스토리]
오버라이딩 : 상위 클래스에서 정의한 메서드를 하위 클래스가 받아 재정의하는것.
===> 메소드 오버로딩은 결국 같은 기능으로 갈 수 있지만, 오버라이딩은 다른 기능이 될 수 있음
final은 마지막, 최종적이라는 의미로 java에서 final 키워드는 상수나 메소드,클래스를 정의한 뒤 변경하지 못하게 할때 사용한다.
static은 정적이라는 의미로 클래스 멤버를 선언할 때 사용하는 키워드 이다.
[출처] https://goodncuteman.tistory.com/4
java.lang.String
C언어에서는 문자열을 char형 배열로 표현하지만, 자바에서는 문자열을 위한 String이라는 클래스를 별도로 제공합니다.
String 클래스에는 문자열과 관련된 작업을 할 때 유용하게 사용할 수 있는 다양한 메소드가 포함되어 있습니다. 이러한 String 클래스는 java.lang 패키지에 포함되어 제공됩니다.
String 인스턴스는 한 번 생성되면 그 값을 읽기만 할 수 있고, 변경할 수는 없습니다. 이러한 객체를 자바에서는 불변 객체(immutable object)라고 합니다.
즉, 자바에서 덧셈(+) 연산자를 이용하여 문자열 결합을 수행하면, 기존 문자열의 내용이 변경되는 것이 아니라 내용이 합쳐진 새로운 String 인스턴스가 생성되는 것입니다.
프로그램에서 사용하는 변하지 않는 모든 값을 뜻 함 (숫자, 문자, 논리 값 등)
모든 리터럴은 상수 풀(Constant Pool)에 저장되어 있다.
상수 풀에 저장될때 정수는 int, 실수는 double로 저장된다.
리터럴마다 하나의 방을 새로 만드는 느낌
출처: https://memostack.tistory.com/207 [MemoStack:티스토리]
모든 리터럴은 상수 풀에 저장되어 있음
final을 이용해 선언하면 변하지 않는 상수(Constant)값이 됨.
상수 풀은 구현 시에 HashMap을 이용한다.
new연산자로 선언할 떄는 Heap영역에 String객체를 선언하는 것이고
변수선언으로 바로 "Java"(리터럴)를 넣었을 떄에는 상수풀로 그 주소를 꽂아버림
따라서 주소값을 비교하는 ==을 이용했을떄 false가 반환됐음.
모든 클래스의 최상위 클래스
java.lang.Object 클래스
모든 클래스는 Object 클래스에서 상속 받음
모든 클래스는 Object의 메서드를 사용할 수 있음(총 11개)
모든 클래스는 Object 클래스의 메서드 중 일부는 재정의 할수있음(근데 final로 선언된 메서드는 안됨)
JDK의 컴파일러가 자바 바이트 코드에 extends Object를 자동으로 추가함
메소드 : 특정 기능을 수행하기 위한 명령문의 집합체.
생성자 : 객체를 생성할떄 객체의 필드를 초기화 할수있게 하는 역할을 함.
필드 : 클래스에 포함된 클래스 변수 / 인스턴스 변수 / 로컬 변수를 의미함.
1. 생성자 오버로딩
2. 디폴트 생성자란?
자바에서 제네릭(generic)이란 데이터의 타입(data type)을 일반화한다(generalize)는 것을 의미합니다
package string;
public class StringBuilderTestRV {
public static void main(String[] args) {
String javaStr = new String("Java"); //객체 생성 후 초기화
System.out.println(javaStr);//toString()에 의해 반환
System.out.println("javaStr 문자열 주소 :" + System.identityHashCode(javaStr));//toString 뚫고 해시값 보는법.
//1365202186 ==> 주소값
// ********** : StringBuilder 클래스
StringBuilder buffer = new StringBuilder(javaStr); //StringBuilder 생성자에 의해 새로 만들어진 객체 = 주소값 다름
System.out.println("연산 전 buffer 문자열 주소 :" + System.identityHashCode(buffer));
//1651191114 ==> 주소값
// .append() ==> 추가하기위해 쓰는 메서드
buffer.append(" and"); //문자열 변경중
buffer.append(" android"); //문자열 변경중
buffer.append(" programming is fun!!!"); //문자열 변경중
System.out.println(buffer); //변경된 문자열 탄생 //주소값은 문자열 변경 전후로 변화없음 //객체는 계속 스트링빌더의 객체.
// buffer의 문자열 주소 값은 변화가 없음
System.out.println("연산 후 buffer 문자열 주소 :" + System.identityHashCode(buffer));
//1651191114 ==> 주소값
javaStr = buffer.toString(); //스트링버퍼로 바꾼 값이 buffer에 있고 투스트링(문자열반환)으로 자바에 다시 넘겨서 덧씌움
System.out.println(javaStr);
System.out.println("새로 생긴 javaStr 문자열 주소 :" + System.identityHashCode(javaStr));
//1586600255 ==> 주소값
}
}
모든 클래스의 최상위 클래스인 Object클래스에 정의된 메서드
해당 객체가 가진 정보나 값들을 문자열로 만들어 반환시키는 역할
보통은 클래스 내에서 오버라이딩해서 사용함.
근데 보통 String (변수명)을 선언하고 변수명을 입력해 출력해도 자동으로 toString()이 호출됨.
===> 주소값이든 뭐든 문자화해서 반환함.
추상클래스(그냥 개인적으로 공부)