
📃 요약
자바는 웹 프로그램을 개발하는데 특화된 컴파일 언어이자 벡엔드 개발 전문 언어임. 플랫폼에 독립적이라서 어떤 운영체제(OS)에서도 실행이 가능하며 가상머신을 통해 실행됨
요소 기술 :
Basic : 자바
📃 기술 구현
스펙 :
intellij java
📃 Optional
자바에서는 null 포인터 예외가 발생할 수 있고, 이것은 다른 정상적인 기능까지 다운시켜서 서비스에 치명적인 부분임. 초기에는 없었으나 자바 버전이 올라가면서 null 포인터 예외를 사전에 방지하기 위해 추가로 나온 클래스
1) :
- Optional.of(값) : Optional 클래스에 값 넣기
- Optional.empty() : Optional 클래스 초기화 (아무 값도 없는 클래스 생성)
- optional.isPresent() : Optional 안에 객체가(값) 있는지 없는지 체크
- optional.get() : Optional 안에 있는 객체 조회
- optional.orElse(“”) : Optional 안에 있는 객체 조회해서 없으면 “” 값으로 대체 출력
Optional<String> optStr = Optional.of("abcde"); // abcde 문자열 객체 생성 // .get() : Optional 값을 가져오기 System.out.println("optStr=" + optStr.get()); System.out.println("-------------------"); Optional optional = Optional.of(0); // 0을 저장 Optional optional2 = Optional.empty(); // 빈 객체 생성 // Optional 안에 객체가(값) 있는지 없는지 체크 System.out.println(optional.isPresent()); // 있으면 true System.out.println(optional2.isPresent()); // 있으면 false System.out.println("-------------------------------"); System.out.println(optional.get()); // 값 가져오기 // System.out.println(optional2.get()); // 값 가져오기 , 에러 (NoSuchElementException 발생) System.out.println(optional2.orElse("없음"));
📃 Generic
컬렉션 프레임워크 자료구조에서 데이터를 넣을때 자료형을 제한하기 위한 용도로 나온 새로운 표기법 주로 <자료형> 형태로 사용함
사용법 :
ArrayList<자료형> 변수 = new ArrayList<>();
<자료형> : 향상된 배열에 들어갈 자료형을 제한하여 다른 자료형이 들어가면 에러가 발생함
ArrayList productArrayList = new ArrayList<>();
향상된 배열에 들어간 자료를 꺼낼때는 다시 강제형변환을 통해 꺼내야함
Tv tv = (Tv)productArrayList.get(0);
<? extends 클래스> : 클래스 의 자식 클래스만 가능
ArrayList<? extends Tv> list
<? super 클래스> : 클래스 의 부모 클래스만 가능
ArrayList<? super Product> list
<?> : 모든 클래스 가능
ArrayList<? super Product> list
GenericApplication.java
package chap15.sec01.exam02; import java.util.ArrayList; public class GenericApplication { public static void printAll(ArrayList<Product> list) { for(Object p : list) { System.out.println(p); } } public static void printAll2(ArrayList<? extends Tv> list) { for(Object p : list) { System.out.println(p); } } public static void printAll3(ArrayList<? super Product> list) { for(Object p : list) { System.out.println(p); } } public static void printAll4(ArrayList<?> list) { for(Object p : list) { System.out.println(p); } } public static void main(String[] args) { // TODO: 여기부터 코딩 ArrayList<Product> productArrayList = new ArrayList<>(); ArrayList<Tv> tvArrayList = new ArrayList<>(); // List<Tv> tvList2 = new ArrayList<>(); // 가능 , 다형성 // ArrayList 제네릭스가 Product(부모) 이므로 아래는 실행은 가능 : // 컬렉션 자료구조는 함수의 매개변수로 가능 , 일반함수는 매개변수로 안됨 productArrayList.add(new Tv()); productArrayList.add(new Audio()); // ArrayList 저장된 객체를 조회할때 형변환 필요 Tv tv = (Tv)productArrayList.get(0); Audio audio = (Audio) productArrayList.get(1); // ArrayList 제네릭스가 Tv 이므로 Tv 객체만 넣어야함 tvArrayList.add(new Tv()); tvArrayList.add(new Tv()); System.out.println("-------(참고)일반 함수의 매개변수--------"); // 제네릭스가 Product 이므로 가능 // 일반함수의 매개변수는 그 타입만 가능 printAll(productArrayList); // Tv{name='동성 Tv'}, Audio{name='동성 Audio'} // 제네릭스가 Tv 이므로 에러 발생 // printAll(tvArrayList); // 에러 발생 System.out.println("------제네릭스의 특별한 형태-------"); // 제네릭스의 특별한 형태 // <? extends Tv> 이면 Tv 의 자식 클래스만 가능 // printAll2(productArrayList); // 불가능 System.out.println("-----<? extends Tv>------"); printAll2(tvArrayList); // 가능 Tv{name='동성 Tv'},Tv{name='동성 Tv'} // <? super Product> 이면 Product 의 부모 클래스만 가능 System.out.println("------<? super Product>-------"); printAll3(productArrayList); // 가능 Tv{name='동성 Tv'}, Audio{name='동성 Audio'} // printAll3(tvArrayList); // 불가능 // <?> 이면 모든 자료형 이 가능 System.out.println("------<?>-------"); printAll4(productArrayList); // 가능 Tv{name='동성 Tv'}, Audio{name='동성 Audio'} printAll4(tvArrayList); // 가능 Tv{name='동성 Tv'},Tv{name='동성 Tv'} } } class Product { } class Audio extends Product { } class Tv extends Product { }
📃 Stream
1. Stream은 함수형 프로그래밍에서 차용한 객체로 내부적으로 반복문이 실행됨 2. Stream은 정렬된 결과를 컬레션이나 배열에 담아 결과내보내기(return) 할수있다. ( collect ) 3. Stream은 함수(메소드) 체이닝이 사용되며(jquery 비슷) 4. Stream 사용 규칙은 정의 - 가공 - 결과내보내기 , 3단계로 이루어지며 함수(메소드) 체이닝을 이용한다. 5. Stream 은 원본 데이터를 바꾸지 않고 복사본을 사용한다.
사용법 : forEach : 단순출력
list.forEach(s -> System.out.println(s));
사용법 : map : 가공출력
스트림 사용 :
1) 정의 : list.stream()
2) 가공 : map(s -> s.toUpperCase())
3) 결과내보내기 : collect(Collectors.toList())
List list2 = list.stream().map(s -> s.toUpperCase()).collect(Collectors.toList()); // 반복문이 코드상에 노출X list2.forEach(s -> System.out.println(s));
사용법 : filter : 제한출력
1) 정의 : list.stream()
2) 가공 : filter(s -> s.length() > 3)
3) 결과내보내기 : collect(Collectors.toList())
List list3 = list.stream().filter(s -> s.length() > 3).collect(Collectors.toList()); list3.forEach(s -> System.out.println(s));
List<String> list = new ArrayList<>(); list.add("apple"); list.add("ball"); list.add("car"); list.add("daddy"); list.add("ear"); list.add("fox"); // forEach : 단순출력 list.forEach(s -> System.out.println(s)); // list.forEach(System.out::println); // stream 사용 규칙 : 1) 정의 : list.stream() // 2) 가공 : map(s -> s.toUpperCase()) // 3) 결과 내보내기(return) : collect(Collectors.toList() System.out.println("---------map----------"); // 스트림 사용 : // 1) 정의 : list.stream() // 2) 가공 : map(s -> s.toUpperCase()), filter, distinct(중복제거) 등 다양한 함수가 있음 // 3) 결과내보내기 : collect(Collectors.toList()) - 리스트로 결과내보내기 // map // 요소들을 조건에 해당하는 값으로 변환 해준다.(가공) System.out.println("==========stream1========="); List<String> list2 = list.stream().map(s -> s.toUpperCase()).collect(Collectors.toList()); // 반복문이 코드상에 노출X list2.forEach(s -> System.out.println(s)); // List<String> list2 = list.stream().map(String::toUpperCase).collect(Collectors.toList()); // 반복문이 코드상에 노출X // list2.forEach(System.out::println); System.out.println("---------filter----------"); // filter // 문자 3자 이상만 : 일부 데이터만 걸러내기 List<String> list3 = list.stream().filter(s -> s.length() > 3).collect(Collectors.toList()); list3.forEach(s -> System.out.println(s)); System.out.println("----------Map 으로 결과 내보내기 : Collectors.toMap(키, 값)--------"); // Map map = list.stream().filter(s -> s.length() > 3).collect(Collectors.toMap(s -> s, s-> s.length())); map.forEach((a, b) -> System.out.println(a + " " + b));
📃 (참고)함수형 인터페이스 / 제네릭 함수
1. 모든 코딩은 함수로 만들어서 코딩한다.(매개변수, 리턴값) 라는 함수형 프로그래밍의 기법을 자바에서 받아 들여 만든 인터페이스 2. 자바에서는 5가지 함수형태를 미리 정해놓고 사용함, 각각의 인터페이스는 실행되는 고유 함수 들이 있음 - Runnable 함수 : 매개변수(X), 반환값(X) ex) void run() - Supplier 함수 : 매개변수도(X), 반환값(O) ex) T get() - Consumer 함수 : 매개변수(O), 반환값(X) ex) void accect(T t) - Function 함수 : 일반적인 함수, 매개변수(O), 반환값(O) ex) T apply(T t) - Predicate 함수 : 매개변수(O), 반환값 이 boolean(참/거짓) ex) boolean test(T t)
public class RamdaApplication { // 제네릭 함수 : 제네릭을 매개변수에 사용하는 함수, 반환타입 앞에 <T>를 붙임 // 제네릭 함수 : static <T> 반환타입 함수명(매개변수타입 매개변수명...) {} // 1~100까지 중 10개의 랜덤 숫자 넣기 static <T> void makeRandomList(Supplier<T> s, List<T> list) { for (int i = 0; i < 10; i++) { list.add(s.get()); // s.get() : 매개함수의 값을 조회하는 함수 } System.out.println(list); } public static void main(String[] args) { // TODO: 이것만 코딩 // 함수형 인터페이스 : 모든 코딩은 함수로 만들어서 코딩한다.(매개변수, 리턴값)(철학) Supplier<Integer> s = () -> (int)(Math.random()*100) + 1; // 1 ~ 100까지 램덤수 함수 List<Integer> list = new ArrayList<>(); // 전역 함수 makeRandomList(s, list); } }