* 표준 애너테이션 : 특정 프로그램을 위한 주석 - @키워드를 붙여서 사용 - 오버라이딩 시 오타 방지목적 // @Overriding - 관련경고 억제 // @SuppressWarnings({"deprecation", "unused", "null"}) - 함수형 인터페이스의 선언되었는지 확인 // @FunctionalInterface
* 메타 애너테이션 : 애너테이션을 위한 애너테이션, 적용대상 또는 유지기간을 정의 - @Target : 적용할 대상 지정 - @Documented : javadoc으로 작성한 문서에 포함되도록 하는 애너테이션 설정 - @Inherited : 하위 클래스가 애너테이션을 상속 / 하위 클래스도 상위 클래스에 붙은 애너테이션들이 동일하게 적용 - @Retention : 애너테이션의 지속 시간을 결정 - @Repeatable : 애너테이션을 여러 번 붙일 수 있도록 허용 // @Repeatable(Works.class) , @Work("코드 업데이트")
* 사용자 정의 애너테이션 - @interface 애너테이션명 { // 인터페이스 앞에 @기호만 붙이면 애너테이션을 정의할 수 있습니다. 타입 요소명(); } // 애너테이션 요소를 선언
# 람다식
* 람다식 : 단 하나의 추상메서드만 정의되어야함 - 메서드를 좀더 간단하고 편리하게 표현하기 위해 고안된 문법요소 - (매개변수 인자) -> { 수행기능 식 정의 / return 생략가능 } - 실행문이 하나만 존재할 때 중괄호 생략 가능 - 매개변수 타입을 쉽게 유추할 수 있는경우 매개변수 타입 생략 가능 // 많은 경우 유추가 쉬워 대부분 생략 가능 - 람다식은 객체이며 익명클래스라 할 수 있음 - 람다식과 인터페이스의 메서드가 1:1로 매칭되어야함 ExampleFunction exampleFunction = (num1, num2) -> num1 + num2 System.out.println(exampleFunction.sum(10,15)) @FunctionalInterface // 컴파일러가 인터페이스가 바르게 정의되었는 지 확인할 수 있도록 interface ExampleFunction { public abstract int sum(int num1, int num2); }
- 클래스 :: 메서드 // 정적메서드 참조 - 참조변수 :: 메서드 // 인스턴스 메서드 - IntBinaryOperator operato = Math :: max; //메서드 참조 - 클래스 :: new // 생성자 참조 Function<String, Member> function1 = Member::new; Member member1 = function1.apply("kimcoding");
# 스트림: 컨베이어벨트 처럼 다양한 데이터소스를 통합된 방식으로 핸들링 하기 위함 - 컬렉션들은 모두 .stream 호출 가능 - 사용 예제 Intstream stream = Arrays.stream(arr).forEach(n->n); - 스트림 인터페이스 안에 다양한 메서드들이 이미 만들어져 있음
* IntStream 인터페이스 // 숫자와 관련된 경우 권장 - sum 과 average 사용가능
* 중간연산 - filter() : 추출 // ex 길이가 5이상인 요소 - map() : 변화 // 객체가 가지고있는 get이나 set등을 호출할 때 사용 - sorted() : 정렬 - .peek() 주로 디버깅할때 사용 // .peek(n-> System.out.println(n))
* 최종연산 - .forEach() : 내부요소를 하나씩 꺼낼 때 사용 - .count() : 요소의 개수 - sum() : 요소들의 합 - collect : 최종형태 만들어줌 // .collect(Collectors.toList()); <- 최종형태 리스트
* List : 데이터의 순서가 유지, 중복저장 가능 // Collection인터페이스 - ArrayList, Vector, Stack, LinkedList
* Set : 데이터 순서유지x, 중복저장x // Collection 인터페이스 - HashSet, TreeSet
* Map : 키와 값의 쌍으로 데이터를 저장 / 순서유지x, Key 중복저장x Value 중복저장 가능 - HashMap, HashTable, TreeMap, properties
* Collection인터페이스 : List/Set의 공통점을 정의한 인터페이스 - boolean / add(), addAll() // 컬렉션 추가 - boolean / contains(), containsAll() // 주어진 객체 및 컬렉션 저장여부 리턴 - Iterator / iterator() //컬렉션의 iterator를 리턴 - boolean / equals(Object o) //컬렉션이 동일한지 여부를 확인 - boolean // isEmpty() 컬렉션이 비어있는지 여부를 확인 - int / size() // 저장되어 있는 전체 객체 수를 리턴 - void / clear() // 컬렉션에 저장된 모든 객체를 삭제 - boolean / remove(Object o) / removeAll(Collection c) // 주어진 객체 및 컬렉션을 삭제하고 성공 여부를 리턴 - boolean / retainAll(Collection c) // 주어진 컬렉션을 제외한 모든 객체를 컬렉션에서 삭제하고, 컬렉션에 변화가 있는지의 여부를 리턴 - Object[] / toArray() // 컬렉션에 저장된 객체를 객체배열(Object [])로 반환 - Object[] / toArray(Object[] a) // 주어진 배열에 컬렉션의 객체를 저장해서 반환
* List<E> : 객체를 저장하면 자동으로 인덱스 부여, 검색/추가/삭제 등 기능제공 - add(int index, Object element)// 주어진 인덱스에 객체를 추가 - addAll(int index, Collection c)// 주어진 인덱스에 컬렉션을 추가 - set(int index, Object element)// 주어진 위치에 객체를 저장 - get(int index)// 주어진 인덱스에 저장된 객체를 반환 - indexOf(Object o) / lastIndexOf(Object o)// 순방향 / 역방향으로 탐색하여 주어진 객체의 위치를 반환 - listIterator() / listIterator(int index)// List의 객체를 탐색할 수 있는ListIterator 반환 / 주어진 index부터 탐색할 수 있는 ListIterator 반환 - subList(int fromIndex, int toIndex)// fromIndex부터 toIndex에 있는 객체를 반환 - remove(int index) // 주어진 인덱스에 저장된 객체를 삭제하고 삭제된 객체를 반환 - remove(Object o)// 주어진 객체를 삭제 - sort(Comparator c)// 주어진 비교자(comparator)로 List를 정렬
* ArrayList<String> arrayList = new ArrayList<>(); : 객체만 저장할 수 있음 / 스스로 크기를 늘려줌 // 배열타입 - arrayList.add("Hello"); // 문자열 추가 - arrayList.get(0); // 첫번째 추가된값 리턴 - for(String el : arrayList) sout("el = " +el); // 배열 순회 - ArrayList.clear() // 담겨있는 모든 객체 삭제
* LinkedList : 데이터를 효율적으로 추가/삭제/변경하기위해 사용 - 배열과 달리 불연속적으로 존재, 데이터끼리 연결되어있음 - 배열처럼 데이터를 이동하기 위해 복사할 필요 없어 처리속도가 훨씬 빠름
* ArrayList / LinkedList 차이 - 데이터의 잦은 변경이 예상된다면 LinkedList 사용 - 데이터의 개수가 변하지 않는다면 ArrayList사용 // 데이터 검색이 비교적 빠름
* Iterator : 컬렉션에 저장된 요소들을 순차적으로 읽어오는 역할
- hasNext()// 읽어올 객체가 남아 있으면 true를 리턴하고, 없으면 false를 리턴 - next()// 컬렉션에서 하나의 객체를 읽어옵니다. 이 때, next()를 호출하기 전에 hasNext()를 통해 읽어올 다음 요소가 있는지 먼저 확인 - remove()// next()를 통해 읽어온 객체를 삭제합니다. next()를 호출한 다음에 remove()를 호출
- 사용법
ArrayList<String> list = ...;
Iterator<String> iterator = list.iterator(); // 해당 컬렉션과 같은 타입이어야함(String)while(iterator.hasNext()) { // 읽어올 다음 객체가 있다면
String str = iterator.next(); }// next() 를 통해 다음 객체를 읽어옵니다.
- Iterator 사용없이 for-each문으로 대체 가능
ArrayList<String> list = ...;
for(String str : list) {
*Set<E> : 중복을 허용하지 않고 저장순서를 유지하지 않는 컬렉션
- boolean / add(Object o)// 주어진 객체를 추가하고, 성공하면 true를, 중복 객체면 false를 반환합니다. - boolean / contains(Object o)// 주어진 객체가 Set에 존재하는지 확인합니다. - boolean / isEmpty()// Set이 비어있는지 확인합니다. - Iterator / Iterator()// 저장된 객체를 하나씩 읽어오는 반복자를 리턴합니다. - int / size()// 저장되어 있는 전체 객체의 수를 리턴합니다. - void / clear()// Set에 저장되어져 있는 모든 객체를 삭제합니다. - boolean / remove(Object o)// 주어진 객체를 삭제합니다.
* HashSet - iterator을 이용해 요소 출력가능
*TreeSet : 이진탐색 트리형태로 저장 - 하나의 부모 노드가 최대 두 개의 자식 노드와 연결되는 이진 트리(Binary Tree)의 일종으로, 정렬과 검색에 특화된 자료 구조 - 최상위 노드를 루트라고 함 - 모든 왼쪽 자식의 값이 루트나 부모보다 작고 오든 오른쪽 자식의 값이 루트나 부모보다 큰값을 가짐
* Map<K, V> - Entry객체는 키와 값을 각각 Key 객체와 Value객체로 저장
- object / put(Object key, Object value) // 주어진 키로 값을 저장합니다. 해당 키가 새로운 키일 경우 null을 리턴하지만, 동일한 키가 있을 경우에는 기존의 값을 대체하고 대체되기 이전의 값을 리턴 - boolean / containsKey(Object key)// 주어진 키가 있으면 true, 없으면 false를 리턴 - boolean / containsValue(Object value)// 주어진 값이 있으면 true, 없으면 false를 리턴 - Set / entrySet()// 키와 값의 쌍으로 구성된 모든 Map.Entry 객체를 Set에 담아서 리턴. - Object / get(Object key)// 주어진 키에 해당하는 값을 리턴 - boolean / isEmpty()// 컬렉션이 비어 있는지 확인. - Set / keySet()// 모든 키를 Set 객체에 담아서 리턴 - int / size()// 저장된 Entry 객체의 총 갯수를 리턴 - Collection / values()// 저장된 모든 값을 Collection에 담아서 리턴 - void / clear()// 모든 Map.Entry(키와 값)을 삭제 - Object / remove(Object key)// 주어진 키와 일치하는 Map.Entry를 삭제하고 값을 리턴
*HashMap : 많은 양의 데이터를 검색하는데 뛰어난 성능
- boolean / equals(Object o) // 동일한 Entry 객체인지 비교 - Object / getKey() // Entry 객체의 Key 객체를 반환 - Object / getValue() // Entry 객체의 Value 객체를 반환 - int / hashCode() // Entry 객체의 해시코드를 반환 - Object / setValue(Object value) // Entry 객체의 Value 객체를 인자로 전달한 value 객체로 교체
- 사용법 hashMap.put(key, value); // 묶여서 엔트리 객체로 저장 / 반환값 Set
* public static final int ~ * enum Season {SPRING, SUMMER, FALL, WINTER} // 순서대로 0,1,2,3 * name()//정의한 열거문자 리턴(배열에서사용) - ordinal()//순번출력 - compareTo - valueOf(String name)//문자열의 열거 객체 리턴 - values()//모든 열거 배열로 리턴
# 제네릭
* <T>타입 매개변수 <-- 타입을 지정해주면 그때 결정됌 - public T item; <---이런식으로 쓸 수 있음 - Basket<String> stringBasket = new basket<>(item:"Apple"); - Basket<Integer> integerBasket = new Basket<>(item:369);
* Basket<T extends Flower> // 인스턴스화 할때 Flower 클래스 하위클래스만 지정하도록 or 인터페이스 구현한 클래스만 받도록 제한 - class Basket<T extends Flower & Plant> // 상속받으며 특정인터페이스를 구현한타입으로 지정제한
* 특정 메서드만 제네릭으로 선언도 가능 - public <T> void add(T element) - 클래스 제네릭 <T>와 메서드제네릭<T>는 다르게 구분 // 동일명이더라도 다르게 구분
*와일드카드 - <? extends 클래스명>(하위)혹은 <? super 클래스명>(상위)로 사용
- <T extends 클래스명>과 뭐가 다른지 모르겠음...
# 예외처리
* 모든 예외의 최고 상위클래스 Exception - 일반 예외클래스 : 모든 Exception클래스들 // 런타임시 발생하는 RuntimeException클래스들 제외 - 실행 예외클래스 : 런타임시 발생하는 RuntimeException클래스들 // 형변환, 배열범위지정, 널포인터오류 등
* 사용법 try{ 여기코드실행하고 } catch (해당에러){ 만약 해당에러가 발생하면 여기있는 코드를 실행 println(해당에러)로 확인 가능 } finally{ 에러가 발생 하던 안하던 여기있는 코드 무조건 실행 }
* 에러정보 얻는 방법 3가지 - e.getMessage(); // println과 함께사용 - e.toString() ; //println과 함께사용 - e.printStackTrace();
* 예외전가 (throw) : exception이 발생함에 대응할것을 강제함<-- 즉 메서드 내부가 아닌 호출하는 곳에서 try catch를 사용하게함 - void ExampleMethod() throws Exception{} // thow 형식 - 고의적으로 예외를 발생시켜 프로그램 비정상 종료를 방지할때도 사용
* 참조변수의 타입변환 : 사용할 수 있는 멤버의 개수를 조절하는 것 1. 서로 상속관계에 있는 상위 클래스 - 하위 클래스 사이에만 타입 변환이 가능 2. 하위 클래스 타입에서 상위 클래스 타입으로의 타입 변환(업캐스팅)은 형변환 연산자(괄호)를 생략할 수 있다. 3. 반대로 상위 클래스에서 하위 클래스 타입으로 변환(다운캐스팅)은 형변환 연산자(괄호)를 반드시 명시
* 참조_변수 instanceof 타입 - 리턴값이 true가 나오면 타입변환 가능 false면 불가능 - ex) Animal cat = new Cat(); System.out.println(cat instanceof Object); //true
# 추상화 : 공통점을 뽑아서 외부로 추출 // abstract / interface
* abstract - 추상클래스 : 클래스의 공통된기능을 모아서 상속을 해줄 필요가 있지만 스스로 인스턴스화를 못함 - 추상 메서드 : 추상클래스는 추상 메서드를 가질 수 있음 // 기능구현은 상속받은 이후 오버라이딩 해서 재정의!! <-- 클래스마다 다른 기능구현 가능 - 추상 메서드를 하나 이상 포함해야함
* interface : (implements) - 인터페이스는 강제로 @override 해줘야함 - 공통적으로 구현해야할 핵심기능을 정의할때 사용하는듯? - 추상메서드와 상수만을 멤버로 가질 수 있다. - 상수를 정의할 때 public static final을 생략할 수 있음 // 자동으로 내부 모든필드 public static final로 정의 -
* abstract 와 interface차이 - abstract는 필요한 것만 추상메서드로 만들고 interface는 안에있는 모든 내용을 재정의하여 구현해야함 - 추상클래스 다중상속 불가능 / 인터페이스는 다중적 구현 가능
* 부모의 것을 모두 사용할 수 있음 // ex) 클래스 시민, 클래스 서울 extends 시민, 클래스 대전 extends 시민
* 상속보다는 참조를 해서 포함관계를 사용하는 경우가 더 많다. 이것을 판별하는 방법은? - ~은~이다(IS-A) : 상속관계/ ~은~을 가지고있다(HAS-A) : 포함관계 ex) 근로자는 주소이다 x / 근로자는 주소를 가지고 있다.o
* 메서드 오버라이딩 (재정의) - 조건 3가지 : 1. 메서드의 선언부가 상위클래스의 그것과 완전히 일치해야함 2. 접근 제어자의 범위가 상위 클래스의 메서드보다 같거나 넓어야 한다. 3. 예외는 상위 클래스의 메서드보다 많이 선언할 수 없다.
- 상위클래스 타입으로 선언하면 배열로 선언하여 관리할 수 있는 편리성이 있음 // 배열로 한번에 관리하기 Vehicle[] vehicles = new Vehicle[] { new Bike(), new Car(), new MotorBike()}; for (Vehicle vehicle : vehicles) { vehicle.run(); } // 출력값 Bike is running Car is running MotorBike is running
* Super 키워드 - 상위 클래스의 객체 // super.변수 / this.변수로 구분 - Super()는 상위클래스의 생성자를 호출 - spuer()는 생성자 안에서만 사용가능하고 반드시 첫줄에 와야함 // 모든 생성자의 첫줄에는 반드시 this() 혹은 super()가 선언되어야함
* 모든객체의 최고 조상 Object클래스 // 컴파일시 아무런 상속을 받지 않는 클래스에 extends Object를 추가함 - 대표적 메서드 : toString(), equals(), hashCode(), wait(), notify()
# 캡슐화 : 정보은닉에 중점
* import문 : 다른 패키지의 클래스를 사용하기 위해 사용 - 사용법 : import 패키지명.클래스명; 또는 import 패키지명.*; / package practicepack.test2; <-- import문 없이 사용
* 접근제어자의 접근 제한 범위 - private : 동일클래스에서만 접근 가능 - default : 동일 패키지 내에서만 접근 가능 - protected : 동일 패키지 + 다른 패키지의 하위 클래스에서 접근 가능 - public : 접근 제한 없음
* getter 와 setter - private으로 변수 생성하고 public getter/setter 메서드를 통해 데이터 변경 읽어오기
* 멤버 - 필드 : 클래스 내의 변수 // 속성 - 메서드 : 클래스 내의 함수 // 기능 - 이너 클래스 : 클래스 내부의 또다른 클래스
* 멤버x - 생성자 : 클래스의 객체를 생성하는 역할
# 객체 * 객체는 속성 / 기능으로 이뤄져 있다. 속성과 기능은 필드/메서드로 정의
* new 키워드로 객체를 생성 // ex Car bmw= new Car - new 키워드 사용으로 힙메모리에 저장 // 힙메모리는 동적메모리 / 순차적으로 저장x
* 포인터 연산자 '.' 을 통해 객체의 멤버에 접근이 가능 - 필드, 메서드 호출 가능 // 참조변수명.필드명 / 참조변수명.메서드명()
# 필드
* 클래스 변수(static) / 인스턴스 변수 / 지역변수(메서드 안에서만 유효) 세가지로 구분 * 멤버변수 : 클래스변수 / 인스턴스 변수 // 클래스 안에 선언 * 지역변수 : 지역변수 // 메서드 내부 블럭에 선언
* 인스턴스 변수 (힙메모리 저장) <-- 직접 초기화 않해도 강제 초기화 - 인스턴스가 가지는 각각의 고유한 속성을 저장하기 위한 변수 - new 생성자()를 통해 인스턴스가 생성될 때 만들어짐 - 동일한 클래스로부터 생성되지만 객체의 고유한 개별성을 가짐
* 클래스 변수 (ststic 전용 저장공간으로 공유 / 프로그램 실행과 동시에 먼저 메모리 할당) - 인스턴스를 따로 생성하지 않고도 언제든 클래스명.클래스변수명을 통해 사용이 가능 - 한 클래스로부터 생성되는 모든 인스턴스들이 특정 값을 공유해야 하는 경우 static 키워드 사용
*지역 변수 (스택메모리 저장) <-- 변수 생성시 초기화 해야함 - 메서드가 종료되면 소멸 - 한동안 사용되지 않을 경우 가비지컬렉터가 삭제
* Static 키워드(정적 멤버) - 클래스의 멤버(필드, 메서드, 이너 클래스)에 사용하는 키워드 - 객체 생성없이 클래스명 . 멤버명 으로 바로 사용가능 // <-- 형태로 사용 권장( 정적멤버 구분)
# 메서드
* 클래스 메서드 -> 클래스 변수 접근가능 * 클래스 메서드 -> 인스턴스변수 접근 불가(x) // static은 실행과 동시에 먼저 생성되는데 인스턴스 변수는 그 이후 생성되기 때문에 오류발생