람다식
Map 함수형인터페이스로 값 출력하기
// Map
Map<String, String> map = new HashMap<String, String>();
map.put("1", "1");
map.put("2", "2");
map.put("3", "3");
map.put("4", "4");
// iterator 방식
Iterator<Map.Entry<String, String>> entries = map.entrySet().iterator();
while (entries.hasNext()) {
Map.Entry<String, String> entry = entries.next();
System.out.println("key : " + entry.getKey() + ", value :" + entry.getValue());
}
System.out.println();
// 향상된 for문
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println("key : " + entry.getKey() + ", value :" + entry.getValue());
}
System.out.println();
// 함수형 인터페이스
map.forEach((k,v) -> System.out.println(k + "," + v));
이어서 람다식을 사용해본다.
java.util.function 패키지 예제
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
public class LambdaTest4 {
public static void main(String[] args) {
Supplier<Integer> s = () -> (int) (Math.random() * 100) + 1;
Consumer<Integer> c = i -> System.out.print(i + ", ");
Predicate<Integer> p = i -> i % 2 == 0;
Function<Integer, Integer> f = i -> i / 10 * 10; // i의 일의 자리를 없앤다.
List<Integer> list = new ArrayList<>();
makeRandomList(s, list);
System.out.println(list);
printEvenNum(p, c, list);
List<Integer> newList = dosomthing(f, list);
System.out.println(newList);
}
// 메소드의 매개변수를 제한할 떄 제네릭 타입 사용하기
// list에 나온 수들의 1의 자리를 없앤 값 newList에 넣기
static <T> List<T> dosomthing(Function<T, T> f, List<T> list) {
// ArrayList는 사이즈를 지정하지 않아도 기본 크기가 10
// 크기를 지정해두면 속도가 좋아진다
List<T> newList = new ArrayList<T>(list.size());
for (T i : list) {
newList.add(f.apply(i));
}
return newList;
}
// list에서 짝수만 출력하기
static <T> void printEvenNum(Predicate<T> p, Consumer<T> c, List<T> list) {
System.out.print("[");
for (T i : list) {
if (p.test(i)) {
c.accept(i);
}
}
System.out.println("]");
}
// 100 이하의 랜덤 수 10개를 list에 넣기
static <T> void makeRandomList(Supplier<T> s, List<T> list) {
for (int i = 0; i < 10; i++) {
list.add(s.get());
}
}
}
람다식의 메소드 참조 방식 (매개변수 생략, ::)
import java.util.function.BiFunction;
import java.util.function.Function;
public class LambdaTest5 {
public static void main(String[] args) {
// 람다식의 메소드 참조 방식 (매개변수 생략, ::)
// 람다식이 하나의 메소드만 호출하는 경우에는 메소드 참조라는 방식으로 호출할 수 있다.
// 문자열을 정수로 바꿔준다
// Function<String, Integer> f = s -> Integer.parseInt(s);
Function<String, Integer> f = Integer::parseInt; // 메소드 참조
int i = f.apply("100");
System.out.println(i + 100);
// BiFunction<String, String, Boolean> f2 = (s1, s2) -> s1.equals(s2);
// 문자열이 같은지 비교
BiFunction<String, String, Boolean> f2 = String::equals; // 메소드 참조
boolean b = f2.apply("hello", "hello"); // 문자열이 같다
System.out.println(b); // 문자열이 같으므로 true
}
}
✨ System.out.println() 의 메소드 참조 방식
// BiFunction<String, String, Boolean> f2 = (s1, s2) -> s1.equals(s2); // 문자열이 같은지 비교
BiFunction<String, String, Boolean> f2 = String::equals; // 메소드 참조
boolean b = f2.apply("hello", "hello"); // 문자열이 같다
System.out.println(b); // 문자열이 같으므로 true
ArrayList<Integer>list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
//list.forEach(i -> System.out.println(i));
list.forEach(System.out :: println);
많이 쓴다!!
위 코드들은 베이스 코드. 응용에 앞서 베이스코드를 혼자 짤 수 있어야 한다.
대표하는 베이스 코드는 머리 속에 넣어둬야 한다. → 그냥 외워
Stream
: 데이터를 추상화(표준화) 하여 사용하기 편하게 연산하는 방식을 통일한다
배열을 스트림화
package Stream0529;
import java.util.Arrays;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class StreamTest {
// Stream
// 객체형식으로 되어있는 데이터를 다루는 변수 구조 : 배열, 컬렉션
// 데이터를 추상화(표준화) 하여 사용하기 편하게 연산하는 방식을 통일한다
// 중간연산, 최종연산
// 배열을 스트림화 하는 3가지 방식
Stream<String> stream1 = Stream.of("a", "b", "c"); // 가변인자
Stream<String> stream2 = Stream.of(new String[] {"a", "b", "c"}); // 직접입력
Stream<String> stream3 = Arrays.stream(new String[] {"a", "b", "c"}); // Arrays 사용
// 기본형에 IntStream 으로 스트림화 하기
// IntStream IntStream.of(int ...value);
// IntStream intStream.of(int[]);
// IntStream Arrays.stream(int[]);
}
연산자 : map(), filter(), distinct(). forEach() 사용
package Stream0529;
import java.io.File;
import java.util.stream.Stream;
public class StreamTest2 {
public static void main(String[] args) {
File[] fileArr = { new File("Ex1.java"), new File("Ex1.bak"), new File("Ex2.java"), new File("Ex1"),
new File("Ex1.txt") };
// File f1 = fileArr[0];
// System.out.println(f1.getName()); // Ex1.java
Stream<File> fileStream = Stream.of(fileArr);
Stream<String> filenameStream = fileStream.map(File::getName);
filenameStream.forEach(System.out::println);
// 스트림을 다시 생성해서 초기상태로 만들어야한다.
fileStream = Stream.of(fileArr);
// 연산자 : map(), filter(), distinct(). forEach() 사용
fileStream.map(File::getName) // Stream<File> -> Stream<String>
.filter(s -> s.indexOf('.') != -1) // 확장자가 없는 것은 제외
.map(s -> s.substring(s.indexOf('.') + 1)) // 확장자만 유출
.map(String::toUpperCase) // 모두 대문자로 변환
.distinct() // 중복제거
.forEach(System.out::print); // JAVABAKTXT
System.out.println();
}
}
기본형을 스트림화
package Stream0529;
import java.util.stream.IntStream;
public class StreamTest3 {
public static void main(String[] args) {
IntStream intStream = IntStream.of(1, 2, 3, 4, 5);
intStream.forEach(System.out::println);
System.out.println("============");
IntStream.range(1, 5).forEach(System.out::println); // 마지막은 포함하지 않는다
System.out.println("============");
IntStream.rangeClosed(1, 5).forEach(System.out::println); // 마지막까지 포함된다
System.out.println("============");
IntStream.rangeClosed(1, 5).map(n -> n * n).filter(n -> n % 2 == 0).forEach(System.out::println);
// sum(), average(), max(), min()
System.out.println("============");
// 1부터 5까지의 합
int sum = IntStream.rangeClosed(1, 5).sum();
System.out.println(sum);
// 1부터 5까지의 합의 평균 구하기
// getAsDouble() 실수형으로 값을 바꿔준다
double avg = IntStream.rangeClosed(1, 5).average().getAsDouble();
System.out.println(avg);
// 최대값 구하기
int max = IntStream.rangeClosed(1, 5).max().getAsInt();
System.out.println(max);
// 최소값 구하기
int min = IntStream.rangeClosed(1, 5).min().getAsInt();
System.out.println(min);
// anyMatch()
// 스트림의 요소 중 어느 하나라도 주어진 술어를 만족하면 'true'를 반환
boolean any = IntStream.rangeClosed(1, 5).anyMatch(n -> n == 7);
System.out.println(any);
}
}
스트림 정렬
기본정렬 방식에 대한 정의가 클래스 안에 되어있어야 한다!
String 안에 기본 정렬(오름차순)이 있었던 것처럼!
정렬에 대해 복습하며 제네릭으로 바꿔보기)
제네릭
제네릭 적용 전
package come.list;
import lombok.AllArgsConstructor;
import lombok.ToString;
@AllArgsConstructor
@ToString
public class Student implements Comparable {
String name;
int ban;
int no;
int kor, eng, math;
int getTotal() {
return kor + eng + math;
}
float getAverage() {
return (int) ((getTotal() / 3f) * 10 + 0.5) / 10f;
}
// 학생의 이름에 따라 정렬
@Override
public int compareTo(Object o) { // Object o -> Student
if (o instanceof Student) {
Student other = (Student) o; // 값으로 가지고 와서 사용할 수 있다.
// return this.no - other.no; // 오름차순
// return other.no - this.no; // 내림차순
return this.name.compareTo(other.name); // 오름차순
// return this.name.compareTo(other.name) * -1; // 내림차순
}
return -1;
}
}
제네릭 적용 후
public class Student implements Comparable<Student> {
String name;
int ban;
int no;
int kor, eng, math;
int getTotal() {
return kor + eng + math;
}
float getAverage() {
return (int) ((getTotal() / 3f) * 10 + 0.5) / 10f;
}
// 학생의 이름에 따라 정렬
@Override
public int compareTo(Object o) { // Object o -> Student
return this.name.compareTo(s.name); // 오름차순
}
}
스트림으로 정렬해보기
package Stream0529;
public class Student implements Comparable<Student>{
String name;
int ban;
int totalScore;
public Student(String name, int ban, int totalScore) {
this.name = name;
this.ban = ban;
this.totalScore = totalScore;
}
@Override
public String toString() {
return "Student [name=" + name + ", ban=" + ban + ", totalScore=" + totalScore + "]";
}
String getName() {
return name;
}
int getBan() {
return ban;
}
int getTotalScore() {
return totalScore;
}
@Override
public int compareTo(Student s) {
// TODO Auto-generated method stub
return s.totalScore - this.totalScore; // 총점으로 내림차순
}
}
package Stream0529;
import java.util.Comparator;
import java.util.stream.Stream;
public class StreamTest4 {
public static void main(String[] args) {
// 가변형 방식의 스트림
Stream<Student> studentStream = Stream.of(
new Student("남파이", 3, 142),
new Student("강자바", 3, 298),
new Student("최타임", 2, 90),
new Student("코틀린", 5, 273),
new Student("크립트", 7, 194),
new Student("이루비", 2, 210),
new Student("안쿼리", 1, 198)
);
//studentStream.sorted(Comparator.comparing((Student s) -> s.getBan()))
studentStream.sorted(Comparator.comparing(Student::getBan))
.forEach(System.out::println);
}
}
결과 :
Student [name=안쿼리, ban=1, totalScore=198]
Student [name=최타임, ban=2, totalScore=90]
Student [name=이루비, ban=2, totalScore=210]
Student [name=남파이, ban=3, totalScore=142]
Student [name=강자바, ban=3, totalScore=298]
Student [name=코틀린, ban=5, totalScore=273]
Student [name=크립트, ban=7, totalScore=194]
반을 기준으로 오름차순 되어 나온다.
'2024_UIUX 국비 TIL' 카테고리의 다른 글
UIUX _국비과정 0531 [문자기반 보조 스트림, 파일클래스, 네트워크] (0) | 2024.06.24 |
---|---|
UIUX_국비과정 0530 [🍀 스트림] (0) | 2024.06.24 |
UIUX _국비과정 0528 [람다식] (0) | 2024.06.24 |
UIUX _국비과정 0527 [스레드] (1) | 2024.06.24 |
UIUX _국비과정 0524 [JAVA _ Generic, 스레드의 개념] (0) | 2024.06.12 |