package _naver.leejw0199.nestedclass;
public class OuterClass {
//내포 클래스 - 다른 클래스 안에 만들어진 클래스
class Inner{
public int num;
}
//내포 클래스 안에 static 멤버가 있으면 인스턴스 생성없이 사용할 수 있도록 static을 추가
static class StaticInner{
public int num;
public static int share;
}
public void method() {
//메서드 안에 만들어진 클래스 - Local Inner
//메서드 안에서만 사용이 가능한 클래스
class LocalInner{
public int num;
}
}
}
Inner, StaticInner, method 안 LocalInner 사용 방법
AnonymousMain - 인터페이스를 구현한 클래스의 인스턴스 생성
package _api.util.stream.nestedclass;
import java.util.Arrays;
import java.util.Comparator;
//메서드가 1개인 인터페이스
interface Sample{
//추상 메서드 선언
public void display();
}
//인터페이스를 구현한 클래스
class SampleImpl implements Sample{
@Override
public void display() {
System.out.println("클래스를 만들어서 사용");
}
}
public class AnonymousMain {
public static void main(String[] args) {
//인터페이스를 구현한 클래스의 인스턴스를 생성해서 메서드 호출
//인스턴스를 여러 개 만들어야 한다면 클래스를 만드는 것이 효율적
Sample sample = new SampleImpl();
sample.display();
}
}
-------------------------------출력----------------------------------
클래스를 만들어서 사용
인터페이스를 1개 만들고 그 안에 추상메서드 선언
Sample 인터페이스를 implements 받는 SampleImpl 클래스 생성 후 추상메서드 오버라이드
main에서 인터페이스(Sample)를 구현한 클래스(SampleImpl)의 인스턴스를 생성 후 display() 메서드 호출
인스턴스를 여러 개 만들어야 한다면 클래스를 만드는 것이 효율적
AnonymousMain2 - 인터페이스의 클래스를 생성하지 않고 사용
package _naver.leejw0199.nestedclass;
interface Sample2{
public void display();
}
public class AnonymousMain2 {
public static void main(String[] args) {
new Sample2() {
@Override
public void display() {
System.out.println("클래스를 생성하지 않고 사용");
}
}.display();
}
}
-------------------------------출력------------------------------
클래스를 생성하지 않고 사용
추상메서드가 있는 인터페이스 생성 후 main에서 인스턴스를 생성하지 않음
new 인터페이스 이름 (매개변수) { 추상메서드 오버라이드 }.추상메서드 호출;
AnonymousMain3 - 배열의 정렬
package _api.util.stream.nestedclass;
import java.util.Arrays;
import java.util.Comparator;
public class AnonymousMain3 {
public static void main(String[] args) {
//배열의 정렬
String[] arr = {"SM", "JYP", "스타쉽", "YG", "나무엑터스"};
//배열의 내림차순 정렬
//Arrays.sort(배열, 비교를 위한 Comparator<T> 인터페이스를 구현한 클래스의 객체);
//를 호출해야 함
Arrays.sort(arr, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
//이 내부에는 공부를 해야 쓸 수 있음
//지금은 여기까지 틀을 만들어내는 게 중요
return o2.compareTo(o1); //내림차순
}
});
//배열의 요소를 빠르게 확인
System.out.println(Arrays.toString(arr));
//하나씩 확인
for(String app : arr) {
System.out.println(app);
}
}
}
----------------------------------------출력------------------------------------------
[스타쉽, 나무엑터스, YG, SM, JYP]
스타쉽
나무엑터스
YG
SM
JYP
Anonymous Class 작성 부분 Arrays.sort(arr, new Comparator<String>(){ @Override public int compare(String o1, String o2) { //이 내부에는 공부를 해야 쓸 수 있음 return o2.compareTo(o1); } });
package _api.util.stream.nestedclass;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
public class LambdaMain {
public static void main(String[] args) {
//배열의 정렬
String[] arr = {"SM", "JYP", "스타쉽", "YG", "나무엑터스"};
//배열의 내림차순 정렬
//Arrays.sort(배열, 비교를 위한 Comparator<T> 인터페이스를 구현한 클래스의 객체);
//를 호출해야 함
//Comparator 는 메서드가 1개만 존재함
/*
* Arrays.sort(arr, new Comparator<String>() {
* @Override
* public int compare(String o1, String o2) {
* //이 내부에는 공부를 해야 쓸 수 있음
* //지금은 여기까지 틀을 만들어내는 게 중료
* return o2.compareTo(o1); //내림차순
* }
*});
*/
//1. 이 부분과
Arrays.sort(arr, (o1, o2) -> { return o2.compareTo(o1); });
//Comparator 인터페이스는 메서드가 1개 밖에 없으므로 람다로 표현하는 것이 가능
//람다를 만들 때는 인터페이스 이름과 메서드 이름은 중요하지 않음
//매개변수의 개수 와 리턴 타입만 확인하면 됨
//매개변수는 2개 이고, 리턴 타입은 정수
//매개변수가 1개 이면 () 생략 가능
//return 하는 문장만 존재한다면 {} 와 return을 생략하는 것이 가능
//메서드의 매개변수로 코드(함수)를 대입한 것처럼 보이도록 함
//메서드의 매개변수로 코드(함수)를 대입할 수 있는 방식을 함수형 프로그래밍이라고 함
//2. 이 부분 같은 결과 리턴
Arrays.sort(arr, (o1, o2) -> o2.compareTo(o1));
//배열의 요소를 빠르게 확인
//내림차순
System.out.println(Arrays.toString(arr));
}
}
-----------------------------------------출력---------------------------------------------
[스타쉽, 나무엑터스, YG, SM, JYP]
Arrays.sort에서 람다식으로 표현
매개변수는 2개 이므로 ( o1, o2 )에서 ()생략할 수 없음
compareTo 메서드를 이용하면 리턴값이 나오기 때문에 return, {} 생략가능 - 1,2가 다른 점
메서드의 매개변수로 코드(함수)를 대입한 것처럼 보이도록 함
FunctionPackageTest
package chapter14;
import java.util.*;
import java.util.function.*;
public class FunctionPakageTest {
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의 1의 자리 없앰
List<Integer> list = new ArrayList<>();
makeRandomList(s, list);
System.out.println(list);
printEvenNum(p, c, list);
List<Integer> newList = doSomething(f, list);
System.out.println(newList);
} //end main
//변환 작업
static <T> List<T> doSomething(Function<T, T> f, List<T> list) {
List<T> newList = new ArrayList<T>(list.size());
for(T i : list) {
newList.add(f.apply(i)); //일의 자리를 없애서 새로운 list에 저장
}
return newList;
} //end doSomething
//필터링, 소비자
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); //i -> System.out.print(i + ", "); 화면에 i출력
}
System.out.println("]");
} //end printEvenNum
//공급자
static <T> void makeRandomList(Supplier<T> s, List<T> list) {
for(int i = 0; i < 10; i++) {
list.add(s.get());
}
} //end makeRandomList
}
---------------------------------------------------------------------------------
[99, 84, 69, 98, 86, 78, 86, 9, 71, 29]
[84, 98, 86, 78, 86, ]
[90, 80, 60, 90, 80, 70, 80, 0, 70, 20]
PredicateTest
package chapter14;
import java.util.function.*;
public class PredicateTest {
public static void main(String[] args) {
//두개의 함수 하나로 연결하기
Function<String, Integer> f = (s) -> Integer.parseInt(s, 16); //<입력, 출력>
Function<Integer, String> g = (i) -> Integer.toBinaryString(i);
Function<String, String> h = f.andThen(g); //f 적용 후 g 적용해라
Function<Integer, Integer> h2 = f.compose(g); //g 적용 후 f 적용해라
System.out.println(h.apply("FF")); //"FF" -> 255 -> "11111111"
System.out.println(h2.apply(2)); //2 -> "10" -> 16
Predicate<Integer> p = i -> i < 100;
Predicate<Integer> q = i -> i < 200;
Predicate<Integer> r = i -> i%2 == 0;
Predicate<Integer> notP = p.negate(); // i >= 100
Predicate<Integer> all = notP.and(q.or(r));
System.out.println(all.test(150));
String s1 = "abc";
String s2 = "abc";
Predicate<String> p2 = Predicate.isEqual(s1);
boolean result = p2.test(s2);
System.out.println(result);
}
}
----------------------------------------------------------------------------------
11111111
16
true
true
Array(배열) : 크기가 고정인 List { 50, 40, 30, 20, 10 } ▼ Vector : 크기가 가변인 배열 ArrayList : 삽입과 삭제가 가벼움 ▼ Linked List : 다음 데이터를 가리키는 용도, 조회가 느림
내부 반복자를 이용해서 접근하면 반복문이나 빠른 열거를 사용하는 것보다 빠르게 작업을 수행할 수 있음
How 보다 What (어떻게 보다 무엇을?)
Stream 특징
데이터 소스로부터 읽기만 할 뿐 변경하지 않음
Iterator처럼 일회용
작업을 내부 반복으로 처리
최종 연산 전까지는 중간 연산이 수행되지 않음 - 지연된 연산
데이터가 많을 때 Stream<Integer>보다 IntStream가 빠름 - 오토박싱, 언박싱 관련 reduce에는 계산을 하기 위한 Integer → int, int → Integer 과정이 들어가므로 IntStream에서 제공하는 sum을 사용하는게 빠름
병렬 처리 쉬움
Stream API 작업과정
생성 → 중간 작업 → 최종 작업(연산) (중간 작업은 여러 개를 묶어도 됨)
생성은 배열이나 List를 가지고 수행
중간 작업은 스트림의 데이터를 순회하면서 작업을 수행해서 다시 스트림을 리턴하기 때문에 다른 중간 작업을 연속해서 배치하는 것이 가능
최종 작업은 1번만 수행 가능 집계를 수행하는 함수나 forEach 처럼 하나씩 순회하면서 작업을 수행하기 위한 함수 또는 collect 처럼 배열이나 List를 생성해주는 함수를 사용
Stream 생성
1. Collection 인터페이스로부터 상속받은 객체는 stream()이나 parallelStream() 을 호출 → parallelStream()을 호출하면 병렬 처리가 가능한 스트림 2. 배열의 경우는 Arrays.Stream(배열)을 이용해서 생성 → Stream.of()는 객체 배열이나 여러 가지 유형의 객체를 가지고 스트림 생성 3. 일련번호 형태의 정수 스트림은 IntStream.range(start, end) 나 rangeClosed(start, end)를 이용해서 생성하는 것이 가능 4. Random클래스의 ints()/ longs() / doubles() → 난수 생성, 무한 스트림이므로 limit으로 유한 스트림 들거나 크기 지정으로 유한 스트림 생성 가능 5. iterate(), generate()는 람다식을 매개변수로 받아 계산되는 값들을 요소로 하는 무한 스트림 생성 → 기본형 스트림 타입의 참조변수로 다룰 수 업고, 필요하면 mapToInt() 같은 메서드로 변환해야 함 6. csv 파일 List<String[]>로 한번에 가져오기 출처: 챗 gpt
7. 파일과 빈 스트림 생성은 java.io 패키지 확인
//Collections Stream 생성
List<String> list = Arrays.asList("red", "yellow", "green", "blue");
Stream<String> stream = list.stream();
//배열 Stream 생성
String[] array = {"red", "yellow", "green", "blue"};
Stream<String> stream = Arrays.stream(array); //기본 타입, 객체 타입
Stream<String> stream = Stream.of(array); //객체 타입
//일련번호 형태(연속된) 정수 스트림
IntStream intStream = IntStream.range(1, 5); //1, 2, 3, 4
IntStream intStream = IntStream.rangeClose(1, 5); //1, 2, 3, 4, 5
//임의의 수1
IntStream intStream = new Random().ints(); //무한스트림
intStream.limit(5).forEach(System.out::println); //유한 스트림, 5개 요소 출력
//임의의 수2
IntStream intStream = new Random().ints(1, 10); //1~9까지의 숫자 중
intStream.limit(5).forEach(System.out::println); //5개 요소 출력
//임의의 수3
IntStream intStream = new Random().ints(10, 1, 9); //1~8까지의 숫자 중
intStream.forEach(System.out::println); //랜덤으로 10번 출력
//iterate(T seed, UnaryOperator f) - 단항 연산자, 계산 반복
Stream<Integer> intStream = Stream.iterate(0, n -> n + 2);
intStream.limit(10).forEach(System.out::println);
//generate(Supplier s) - 주기만 하는 것. 입력x, 출력o, 이전 결과를 이용해서 다음 요소를 계산하지 않음
Stream<Integer> oneStream = Stream.generate(() -> 1);
oneStream.limit(5).forEach(System.out::println); //'1'만 5번 출력
중간 작업 - 작업을 수행한 후 Stream을 리턴
distinct()
중복 제거
filter(매개변수를 1개 받아서 Boolean을 리턴하는 람다)
람다가 true를 리턴하는 데이터만 모아서 스트림을 생성
map(매개변수를 1개 받아서 리턴하는 람다)
리턴하는 데이터를 모아서 새로운 스트림을 리턴
mapToInt
스트림을 IntStream으로 변환
sorted(비교처리를 수행해주는 람다)
람다를 기준으로 정렬
skip(long n)
n만큼 건너뜀
limit(long n)
n개 만큼 추출
flatMap
중첩된 리스트나 배열을 평면화
Java에서는 Stream, IntStream, LongStream, DoubleStream 객체를 제공함 IntStream은 문자를 생성하고 사용 가능 (ex) chars(): 문자열을 구성하고 있는 문자들의 ASCII 코드값을 스트림 형태로 뽑아줌)
최종 작업 (연산)
count(): 데이터 개수 리턴 max(): 최대값 리턴 min(): 최소값 리턴 average(): 평균 리턴 findFirst(): 첫번째 요소 반환 forEach(): 데이터를 순회하면서 작업 toArray(): 스트림의 요소를 담은 배열 리턴 collect(): 데이터를 모아서 다른 자료형으로 변경 sum(): 스트림의 총 합을 구함 reduce(초기값, 연산): 초기값부터 연산 수행 후 누적 결과 리턴
# 계산에 의해서 나오는 max, min, average는 리턴 타입이 Optional 임 # 스트림의 분할 - partitioningBy # 스트림의 그룹 - groupingBy
//Stream → Collections, 배열
List<String> list = stream.collect(Collectors.toList()); //List, Set
String[] array = stream.toArray(String[]::new); //Array나 특정 컬렉션 지정
Map<String, Integer> map = stream.collect(Collectors.toMap(k -> k, v -> 1, (oldValue, newValue) -> newValue += oldValue)); //키, 초기값, 중복된 키 존재할 경우에 어떻게 합칠지
})
null일 때 지정된 예외를 발생, 매개변수가 없으면 NoSuchElementException
isPresent() - boolean
데이터의 존재 여부를 확인
ifPresent() - void
Optional 객체 값을 가지고 있으면 실행값이 나오고, 없으면 넘어감 반환값이 없으므로 성공 여부를 확인하는 용도로 사용하지 X
최종 작업 (연산) Optional<T> OptionalInt, OptionalLong, OptionalDouble 반환
# 꺼낼 때는 get(), getAsInt(), getAsLong(), getAsDouble() 사용 # OptionalInt.of(0) - 0을 저장 (존재O) OptionalInt.empty() - 빈 객체를 생성 (존재X)
//일반적으로 생각하기에는 평균의 결과가 정수나 실수가 나와야 하는데
//자바에서는 OptionalDouble 이 됨
//Optional이 붙으면 null을 저장할 수 있는 자료형이 되며
//isPresent 라는 메서드를 이용해서 null 여부를 판단하고
//get 이라는 메서드로 데이터를 가져옴
OptionalDouble result = list.stream()
.mapToInt(Integer::parseInt)
.filter(o -> o % 2 == 1)
.average();
//isPresent - 연산을 정상적으로 수행한 경우
if(result.isPresent()) {
System.out.println(result.getAsDouble());
} else {
System.out.println("평균 계산 실패 - 아마도 데이터가 없는 것 같음");
}
//ifPresent - 연산을 정상적으로 수행한 경우
result.ifPresent(average -> {
System.out.println(result.getAsDouble());
//성공한 경우의 추가 동작 구현 가능
});
package _api.util.stream;
import java.util.ArrayList;
public class LoopingMain {
public static void main(String[] args) {
ArrayList <String> list = new ArrayList<>();
list.add("프로그래밍 언어");
list.add("데이터베이스");
list.add("프레임워크");
list.add("소프트웨어 공학");
list.add("Toy Project");
//전체 데이터 출력 - 실행 속도는 가장 빠르지만 list 의 데이터 개수가 변경되면 수정을 해야 됨
System.out.println(list.get(0));
System.out.println(list.get(1));
System.out.println(list.get(2));
System.out.println(list.get(3));
System.out.println(list.get(4));
//반복문 이용
//list의 데이터 개수를 이용해서 순회하면 list의 데이터 개수가 변경되도 수정할 필요 없음
//계속 메서드를 불러
for(int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//변하지 않는 메서드의 호출 결과를 반복문에서 여러번 부르는 것은 자원의 낭비
//메서드를 부르는 것보다 변수를 불러오는게 속도가 훨씬 빠름
//괄호를 열고 닫는건 메서드를 불러오는 것 - stack 생성
int len = list.size();
for(int i = 0; i < len; i++) {
System.out.println(list.get(i));
}
//모든 데이터를 순회하는 경우라면 빠른 열거를 이용하는 것이 효율적
for(String subject : list) {
System.out.println(subject);
}
//빠른 열거는 반복자를 외부에 만들어서 사용하는데 Stream API는 내부 반복자를 사용
//데이터가 많을 때 효율적
list.stream().forEach(subject -> {
System.out.println(subject);
});
}
}
전체 데이터 출력 - System.out.println();
반복문 이용 - for(int i = 0; i < list.size(); i++) { };
변수 설정 후 반복문 이용 // 괄호를 열고 닫는건 stack 생성해서 메서드를 불러오는 것이므로 자원의 낭비 int len = list.size(); for(int i = 0; i < len; i++) { };
빠른 열거, 향상된 for문 사용 // 모든 데이터를 순회하는 경우 향상된 for문 사용하는 것이 효율적 for(String subject : list) { system.out.println(subject); };
내부 반복자를 사용하는 Stream API 이용 + 람다식 list.stream().forEach(subject -> {system.out.println(subject);} );
StreamMain1 - 데이터 출력
package _api.util.stream;
import java.util.ArrayList;
public class StreamMain {
public static void main(String[] args) {
//숫자 형태의 문자열의 리스트
ArrayList<String> list = new ArrayList<>();
list.add("28");
list.add("2");
list.add("3");
list.add("6");
list.add("5");
list.add("9");
//최종 연산을 이용해서 출력
//forEach 는 매개변수 1개를 받고 리턴이 없는 메서드를 매개변수로 받음
//Collection 의 모든 데이터를 매개변수에 대입해서 내용을 수행
//list 안의 데이터를 순차적으로 e에 대입해서 {} 안의 내용을 수행
//최종 작업만 수행해서 데이터 출력, 최종 작업은 한번 밖에 못 함
list.stream().forEach(e -> {System.out.println(e);}); // 28, 2, 3, 6, 9, 5
//데이터 3개만 출력
list.stream().limit(3).forEach(e -> {System.out.println(e);}); // 28, 2, 3
}
}
<String> 타입의 ArrayList 생성 후 add()로
람다식 사용: e -> {System.out.println(e);}
StreamMain2 - 데이터 정렬 후 출력
package _api.util.stream;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.OptionalDouble;
public class StreamMain {
public static void main(String[] args) {
//숫자 형태의 문자열의 리스트
ArrayList<String> list = new ArrayList<>();
list.add("28");
list.add("2");
list.add("3");
list.add("6");
list.add("5");
list.add("9");
//데이터 정렬 후 출력
//오름차순 정렬 2, 28, 3, 5, 6, 9
list.stream().sorted().forEach(e -> {System.out.println(e);});
//내림차순 정렬 9, 6, 5, 3, 28, 2
//sorted 메서드에 내림차순 정렬을 위한 Comparator 인터페이스를 구현한 클래스의 객체를 설정하면 됨
//Comparator 인터페이스는 매개변수가 2개이고 정수를 리턴하는 메서드 1개만 존재함
//Comparator를 생성할 때 new Comparator<String>() {} 중괄호까지 해줘야 add override가 뜸!!!!!!!
1. list.stream().sorted(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}} ).forEach(e -> {System.out.println(e);});
2. list.stream().sorted((o1, o2) -> o2.compareTo(o1)).forEach(e -> {System.out.println(e);});
//숫자의 경우는 크기 비교가 가능해서 별도의 인스턴스를 대입하지 않아도 정렬이 되고
//내림차순을 하고자 하는 경우 reverse 옵션 설정해주면 됨
3. list.stream()
.map(Integer::parseInt)
.sorted(Comparator.reverseOrder())
.forEach(e -> System.out.println(e));
오름차순: 데이터 정렬을 하려면 .sorted() 추가
내림차순 1. Comparator 인터페이스를 구현한 클래스의 객체를 설정 Comparator를 생성할 때 new Comparator<String>() {} 중괄호까지 해줘야 add override가 뜸 2. 람다식 (o1, o2) -> o2.compareTo(o1) 사용 3. map(Integer :: parseInt로 숫자로 변환 후 Comparator.reverseOrder()
//데이터를 정수로 변환해서 정렬
//중간 처리 메서드 중에는 Int로 리턴해주는 mapToInt 라는 메서드가 존재하고
//이 메서드를 사용할 때는 변환에 사용하는 메서드를 설정만 해주면 됩니다.
//클래스이름::메서드이름
list.stream()
.mapToInt(Integer::parseInt)
.forEach(e -> {System.out.println(e);});
int result = list.stream()
.mapToInt(Integer::parseInt)
.sum();
System.out.println(result); //숫자인지 확인
Int로 리턴해주는 mapToInt 메서드 사용: 클래스이름::메서드이름
StreamMain4 - filter를 사용하여 조건에 맞는 데이터 추출
//홀수의 합
//filter: 조건에 맞는 데이터만 추출
//조건에 맞는 추출하고자 할 때는 하나의 매개변수를 받아서 boolean을 리턴하는 람다를 만들어서 대입해주면 됨
/*
int result = list.stream()
.mapToInt(Integer::parseInt)
.filter(o -> o % 2 == 1)
.sum();
System.out.println(result);
*/
//홀수의 평균
//일반적으로 생각하기에는 평균의 결과가 정수나 실수가 나와야 하는데
//자바에서는 OptionalDouble 이 됨
//Optional이 붙으면 null을 저장할 수 있는 자료형이 되며
//isPresent 라는 메서드를 이용해서 null 여부를 판단하고
//get 이라는 메서드로 데이터를 가져옴
OptionalDouble result = list.stream()
.mapToInt(Integer::parseInt)
.filter(o -> o % 2 == 1)
.average();
//연산을 정상적으로 수행한 경우
if(result.isPresent()) {
System.out.println(result.getAsDouble());
} else {
System.out.println("평균 계산 실패 - 아마도 데이터가 없는 것 같음");
}
홀수의 합 정수형 변수 result 생성 - stream()호출 - mapToInt 정수 변환 - filter 홀수만 추출 - sum 합계 구하기 result 값 출력
홀수의 평균 max, min, average를 구할 때 OptionalDouble 타입으로 설정 - stream()호출 - mapToInt 정수 변환 - filter 홀수만 추출 - average 평균 구하기 다만 여기서는 isPresent 메서드를 활용해 null여부 판단 후, get 메서드로 데이터를 가져와야 함
StreamCreate - List, 배열
package chapter14;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;
public class StreamCreate {
public static void main(String[] args) {
//List
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
Stream<Integer> intStream = list.stream(); //list를 Stream으로 변환
intStream.forEach(System.out::print); //최종연산 - Stream 닫힘
//같은 Stream에 대해서 사용하지 못 하고
intStream = list.stream(); //Stream 다시 생성 후 연산 가능
intStream.forEach(System.out::print);
System.out.println();
//배열 - 문자
// Stream<String> strStream = Stream.of(new String[] {"a", "b", "c", "d"});
Stream<String> strStream = Arrays.stream(new String[] {"a", "b", "c", "d"});
strStream.forEach(System.out::println);
//배열 - 숫자
int[] intArr = {1, 2, 3, 4, 5};
IntStream intStream2 = Arrays.stream(intArr);
// intStream2.forEach(System.out::println); 주석 안 걸면 오류남, 최종연산
System.out.println("count = " + intStream2.count()); //IntStream에는 count, sum, average 등 있음
//Stream<Integer>에는 count밖에 없음, 숫자외에도 여러 타입의 스트임이 가능해야하므로 숫자 스트림에만 사용할 수 있는 것은 없음
}
}
------------------------------------------------------------------------------------------------------------------------------
1234512345
a
b
c
d
count = 5
StreamRandomRange
package chapter14;
import java.util.Random;
import java.util.stream.IntStream;
public class StreamRandomRange {
public static void main(String[] args) {
//임의의 수
IntStream intStream = new Random().ints(1, 10); //혹은 ints(10, 1, 9) 하면 limit가 10임
intStream.limit(5).forEach(System.out::print); //limit이 없으면 무한스트림
System.out.println();
//특정 범위의 정수
IntStream rangeStream = IntStream.range(1, 10);
rangeStream.forEach(System.out::print);
System.out.println();
IntStream rangeStream2 = IntStream.rangeClosed(1, 10);
rangeStream2.forEach(System.out::print);
}
}
---------------------------------------------------------------
63769
123456789
12345678910
IterateAndGenerate
package chapter14;
import java.util.stream.Stream;
public class IterateAndGenerate {
public static void main(String[] args) {
//iterate(T seed, UnaryOperator f) 단항 연산자
Stream<Integer> intStream = Stream.iterate(0, n -> n + 2);
intStream.limit(10).forEach(System.out::println);
//generate(Supplier s) : 주기만 하는 것 입력x, 출력o
Stream<Integer> oneStream = Stream.generate(() -> 1);
oneStream
.limit(5)
.forEach(System.out::println);
}
}
--------------------------------------------------------------
0
2
4
6
8
10
12
14
16
18
1
1
1
1
1
StreamMap
package chapter14;
import java.io.*;
import java.util.stream.Stream;
public class StreamMap {
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")
};
Stream<File> fileStream = Stream.of(fileArr);
//map()으로 Stream<File>을 Stream<String>으로 변환
//Stream<String> filenameStream = fileStream.map(File::getName);
Stream<String> filenameStream = fileStream.map((s)-> s.getName()); //File.getName의 리턴 타입 String
filenameStream.forEach(System.out::println); //모든 파일의 이름 출력
System.out.println();
fileStream = Stream.of(fileArr); //스트림을 다시 생성
fileStream.map(File::getName) //Stream<File> -> Stream<String>
.filter(s -> s.indexOf('.')!=-1) //확장자가 없는 것은 제외
// .peek(s -> System.out.printf("filename = %s%n", s))
.map(s -> s.substring(s.indexOf('.')+1)) //확장자만 추출
// .peek(s -> System.out.printf("extension = %s%n", s))
.map(String::toUpperCase) //모두 대문자로 변환
.distinct() //중복 제거
.forEach(System.out::print); //JAVA BAK TXT
System.out.println();
}
}
------------------------------------------------------------------------------------------------------------
Ex1.java
Ex1.bak
Ex2.java
Ex1
Ex1.txt
JAVABAKTXT
StreamFlatMap
package chapter14;
import java.util.*;
import java.util.stream.Stream;
public class StreamFlatMap {
public static void main(String[] args) {
Stream<String[]> strArrStrm = Stream.of(
new String[] {"abc", "def", "jkl"},
new String[] {"ABC", "GHI", "JKL"}
);
// Stream<Stream<String>> strStrmStrm = strArrStrm.map(Arrays::stream);
Stream<String> strStrm = strArrStrm.flatMap(Arrays::stream); //Stream<String>
strStrm.map(String::toLowerCase)
.distinct()
.sorted()
.forEach(System.out::println);
System.out.println();
String[] lineArr = {
"Believe or not It is true",
"Do or do not There is no try",
};
Stream<String> lineStream = Arrays.stream(lineArr);
lineStream.flatMap(line -> Stream.of(line.split(" +"))) //Stream<String>, s.split(" +"): 공백을 구분자로 자른 문자배열
.map(String::toLowerCase)
.distinct()
.sorted()
.forEach(System.out::println);
System.out.println();
}
}
---------------------------------------------------------------------------------------------------
abc
def
ghi
jkl
believe
do
is
it
no
not
or
there
true
try