public class 클래스명<T> {...}
public interface 인터페이스명<T> {...}
<T> == Type
<E> == Element
<K> == Key
<V> == Value
<N> == Number
<R> == Result
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> list = new ArrayList(); // ArrayList의 구현체를 만들어 인터페이스에는 List 타입 변수 list를 만듦, list를 List보다 상위의 인터페이스인 Collection의 변수에 할당해줌
list.add("string");
Collection<String> collection = list;
List<Exception> exceptionList = new ArrayList<>();
Collection<Exception> exceptionCollection = exceptionList;
List<IllegalArgumentException> exceptions = new ArrayList<>();
exceptionCollection.addAll(exceptions);
// exceptionCollection.addAll(list); // 위에서 선언한 String의 list를 넣어봄 > exception을 상속받은 타입의 콜렉션인데 String 타입을 받는 list를 써서 빨간 줄이 생김
}
}
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");
list.add("france");
Stream<String> stream = list.stream();
// stream.map(str -> str.toUpperCase()) // toUpperCase: 대문자로 바꿔주는 함수를 수행
// .forEach(it -> System.out.println(it)); // function이라는 파라미터를 받는다는 것은 람다식을 쓸 수 있다는 말
// 여러 줄 쓰는 경우
stream.map(str -> {
System.out.println(str);
return str.toUpperCase(); // 여러 개를 쓸 경우 {}을 하고 return문을 적어줘야 함
}).forEach(it -> System.out.println(it));
// 람다식을 표현하는 또 다른 방법
// forEach(System.out::println);
}
}
list.stream();의 list
)를 변경하지 않음.stream
을 하면 만들 수 있음 Stream<String> stream = list.stream();
stream.
하고 어떤 메서드를 쓰던지, 원래 있던 데이터에서 하나씩 꺼내 뒤에 있는 연산을 수행해줌(위에 람다 코드에서 소문자 → 대문자 → 소문자 → 대문자로 출력됨을 확인할 수 있음) stream.map(str -> str.toUpperCase()) .forEach(it -> System.out.println(it));
Stream<String> stream = list.stream();
stream.map(str -> {
System.out.println(str);
return str.toUpperCase();
}).forEach(System.out::println); // stream 닫힘. 뒤에 어떤 것도 수행할 수가 없음
System.out.println(list); // stream 에서 대문자로 바꿔서 출력된 것은 stream 안에서만 존재함
// stream.forEach(System.out::println); // error: stream은 이미 닫혔기 때문
Stream<String> stream2 = list.stream(); // 새로운 stream 만들고 싶을 때, list는 변하지 않았으니까 새로운 스트림을 만들어 주면 됨
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) // 두 개만 출력 // 중간 연산
.collect(Collectors.toList()); // 스트림 처리된 것을 하나로 모을 때 다른 리스트로 만들어서 모을 거야 // 최종 연산
System.out.println(result); // 스트림은 stream을 만들면(list.stream()) transformation을 하고(limit()) 결과물을 만드는(collect(Collectors.toList());) 구조를 갖게 됨
System.out.println("list -> transformation -> set"); // list를 set으로 변형하기
Set<String> set = list.stream()
.filter("서울"::equals)
.collect(Collectors.toSet()); // list에 있는 데이터를 하나씩 꺼내서 서울이랑 글자가 같은지 확인하고 같은 거 남길 거야. 그리고 이것을 set의 자료구조로 바꿔서 모아줄 거야
System.out.println(set); // 중복 허용 안함
}
}
import java.util.Arrays;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
String[] arr = {"SQL", "Java", "python"}; // String 배열 선언
Stream<String> stringStream = Arrays.stream(arr); // String 형태의 Stream 만들기, arr는 스트림이 됨.
stringStream.forEach(System.out::println); // 하나씩 개행해서 출력됨
}
}
import org.apache.commons.lang3.tuple.Pair;
import java.util.Arrays;
import java.util.List;
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( // List 만들기
new Sale("Apple", 5000, 0.05f),
new Sale("Orange", 4000, 0.2f),
new Sale("Grape", 2000, 0)
);
// 스트림으로 어떤 과일이 실제로 얼마인지 실구매가를 구해서 출력해보자
sales.stream()
.map(sale -> Pair.of(sale.fruitName, sale.price * (1-sale.discount)))
.forEach(pair -> System.out.println(pair.getLeft() + " 실구매가: " + pair.getRight() + "원 입니다."));
}
}
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<Integer> list = Arrays.asList( 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
System.out.println(list.stream().reduce(0, Integer::sum)); // 0으로 시작해서 stream에서 하나씩 꺼내서 Integer::sum 함수를 실행할 거야
}
}
//이 씨 성을 가진 사람들의 수 구하기
import java.util.Arrays;
import java.util.List;
public class Main {
public static void main(String[] args) {
List<String> names = Arrays.asList("김정우", "김호정", "이하늘", "이정희", "박정우", "박지현", "정우석", "이지수");
System.out.println("이씨성을 가진 친구들: " + names.stream()
.filter(name -> name.startsWith("이"))
.count());
}
}
프로토콜://호스트명:포트번호/경로명/파일명?쿼리스트링#참조
import retrofit2.Call;
import retrofit2.http.GET;
import retrofit2.http.Query;
public interface RetrofitService {
@GET("/api/users/") // 1. 어노테이션 붙여주고 api의 path 입력
Call<Object> getUsers(@Query("page") int page);
}
//Retrofit 을 이용해 API 요청할 수 있는 기본 준비
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
private static final String BASE_URL = "https://reqres.in/";
public static RetrofitService getApi() {
return getInstance().create(RetrofitService.class); // api 요청, 제일 마지막에 입력함
}
private static Retrofit getInstance() {
Gson gson = new GsonBuilder().setLenient().create();
return new Retrofit.Builder().baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.build();
}
}
import retrofit2.Call;
import java.io.IOException;
public class Main {
public static void main(String[] args) { // 데이터 호출
Call<Object> result = RetrofitClient.getApi().getUsers(2); //두 번째 페이지 요청 > 받아주는 데이터는 Call
try { // try-catch 문
System.out.println(result.execute().body()); // execute 를 해야 실제 요청이 날라감, 받은 데이터를 한번 프린트해서 출력
} catch (IOException e) { // IOException 이 발생해서 핸들 해줌, 익셉션 발생 시 익셉션 출력
System.out.println(e.getMessage());
}
}
}
소프트웨어의 가치
: 낮은 비용으로 변화가 가능해야 하고 앞으로의 변화에도 대응할 수 있어야 함
객체지향의 비용 낮추는 방법
: 캡슐화 + 다형성(+추상화)
Argument(아큐먼트) - 인자
: 함수 호출 시, 전달 되는 값
Parameter(파라미터) - 매개 변수
: 전달 되는 인자를 받아들이는 변수
변수
접근 제어자를 사용하는 이유
: 캡슐화가 가능할 수 있도록 돕기 위해
다형성(Polymorphism)
추상화
타입 추상화