1. 제너릭스 ~ Generic: 데이터의 타입을 일반화한다
다양한 타입의 객체들을 다루는 메소드나 컬렉션 클래스에 컴파일 시 타입 체크
동작은 같지만 타입이 달라지는 경우에 유용하게 사용할 수 있다.
->장점
1. 객체 타입을 컴파일 시 체크하기 때문에 안정성이 높아진다
2. 반환값에 대한 타입 변환 및 타입 검사에 들어가는 노력을 줄일 수 있다.
클래스나 메소드에서 사용할 내부 테이터 타입을 컴파일 시 미리 지정하는 방법
*제너릭스를 사용하지 않으면 제너릭 클래스 안에 있는 객체를 꺼낼 때마다 형변환을 해줘야 한다.
*제너릭 타입이 조상클래스와 자손클래스로 다르게 입력되어서는 안된다.
ArrayList<TV> list = new ArrayList<TV>();
ArrayList<TV> list = new ArrayList<SmartTv>(); // 제너릭 에러
List<Tv> list = new ArrayList<Tv>(); // ArrayList가 List를 구현
//클래스 타입 간 다형성 적용, 제너릭 타입은 일치해야 한다.
Collection 클래스의 toArray 메서드 :
default <T> T[] toArray(IntFunction<T[]> generator) {
return toArray(generator.apply(0));
}
Collection 클래스의 ContainsAll 메서드 :
boolean containsAll(Collection<?> c);
Collection 클래스의 addAll 메서드 :
boolean addAll(Collection<? extends E> c);
2. 람다식
식별자 없이 실행가능한 함수(익명함수)
람다식이 비효율적일 수도 있는 이유
1. 람다를 사용해 만든 익명함수는 재사용이 불가능
2. 람다만을 사용할 경우 비슷한 메소드를 중복되게 생성할 가능성이 있어 코드의 비효율이 발생할 수 있다
3. 스트림: 데이터의 흐름
컬렉션을 통해 스트림을 활용: 각각의 데이터에 대해 어떻게 대응할 지를 정할 수 있다.
스트림은 작업을 내부 반복 처리 및 데이터소스를 변경하지 않는다.
컬렉션의 요소를 모두 읽고 나면 닫혀서 재사용이 불가능하다. 그러므로 필요할 경우 재생성을 해야한다.
스트림 프로세스
1. 스트림 생성
Stream<T> Collection.stream() 을 이용하여 해당하는 컬렉션을 기반으로하는 스트림을 생성
2. 중간 연산
중간 단계로써 데이터의 형변환 혹은 필터링, 정렬 등 스트림에 대한 가공 :
map(변환) / sorted(정렬) / skip(스트림 자르기) / limit(스트림 자르기) 등
3. 최종 연산
스트림의 요소를 소모해서 결과를 반환하는 단계, 최종 연산 이후 스트림이 닫히게 되고 더 이상 사용할 수 없다.
최종 연산의 결과값은 단일 값일 수도 있으며 배열 혹은 컬렉션일 수도 있다.
가장 많이 쓰이는 패턴:
collect()를 이용해서 다른 콜렉션으로 바꾸기, reduce를 이용해서 incremental calculation(증분 계산)
람다 & 스트림 예제
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("korea");
list.add("japan");
Stream<String> stream = list.stream();
/*stream.map(str -> str.toUpperCase()). //대문자로 바꿔주는 함수
forEach(it -> System.out.println(it));*/
// 스트림: 데이터 소스를 변경하지 않는다!
stream.map(str -> {
System.out.println(str);
return str.toUpperCase(); //대문자로 바꿔주는 함수, 중괄호 사용시
// 함수처럼 return문을 사용해야 한다
}).forEach(it -> System.out.println(it));
System.out.println(list);
stream.forEach(System.out::println); //스트림
}
}
람다 & 스트림 예제 2)
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("서울");
list.add("부산");
list.add("대구");
list.add("서울")
System.out.println(list);
List<String> result = list.stream() //리스트를 변경
.limit(2) // limit을 이용해 개수
.collect(Collectors.toList()); // 어떻게 모을지, 리스트로 만들거야(toList)
System.out.println(result);
System.out.println("list -> transformation -> set");
/*Set<String> set = list.stream()
.filter(it -> "서울".equals(it)) //서울만 남기는 필터
.collect(Collectors.toSet());*/
Set<String> set = list.stream()
.filter("서울"::equals) //람다식으로 변환
.collect(Collectors.toSet());
System.out.println(set); // set은 중복을 허용하지 않는다
}
}
예제 3)
import java.util.Arrays;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
String[] arr = {"SQL","Java", "Python"};
Stream<String> stringStream = Arrays.stream(arr); // 스트림된 arr
stringStream.forEach(System.out::println); //람다
}
}
예제 4) Map 연산
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
import org.apache.commons.lang3.tuple.Pair;
class Sale {
String fruitName;
int price;
float discount;
public Sale(String fruitName, int price, float discount) {
this.fruitName = fruitName;
this.price = price;
this.discount = discount;
}
}
public class Main {
public static void main(String[] args) {
List<Sale> sales = Arrays.asList(
new Sale("Apple", 5000, 0.05F),
new Sale("Orange", 2000, 0.2F),
new Sale("Grape", 3000, 0)
);
Stream<Sale> saleStream = sales.stream();
saleStream.map(sale -> Pair.of(sale.fruitNmae, sale.price * (1-sale.discount)))
.forEach(pair -> System.out.println(pair.getLeft() + " 실 구매가: " + pair.getRight() + "원"));
}
}
예제 5)
public class Main {
public static void main(String[] args) {
List<Integer> numArr = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Integer result = numArr.stream().reduce(0, Integer::sum);
//reduce와 sum을 활용하여 1부터 10까지 더하게 됩니다.
System.out.println(result);
}
}
4. 네트워킹
라이브러리 리트로핏
HTTP vs HTTPS : HTTPS는 보안된 HTTP 프로토콜
import retrofit2.Call;
import java.io.IOException;
public class Main {
public static void main(String[] args) {
Call<Object> result = RetrofitClient.getApi().getUsers(2);
try{
System.out.println(result.execute().body());
} catch (IOException e) {
System.out.println(e. getMessage());
}
}
}
'자바☕' 카테고리의 다른 글
12. 01 심화 강의 : 인터페이스 (0) | 2022.12.01 |
---|---|
Immutable vs Mutable (0) | 2022.12.01 |
11. 19 내부 클래스/ static vs final vs static final (0) | 2022.11.19 |
오버로딩(Overloading) vs 오버라이딩(Overriding) (0) | 2022.11.18 |
[JAVA] 콘솔에 정수 입력 후, 홀/짝 판단 (0) | 2022.10.28 |