2021. 4. 24. 17:05ㆍJava
스트림
- 다양한 데이터 소스를 표준화된 방법으로 다루기 위한 것
- 데이터 소스를 Stream 을 통해 순차적으로 처리 (데이터의 연속적인 처리)
- 컬렉션 프레임워크(List, Set, Map)은 각자 성격이 달라 사용방법이 다름. 그래서 표준화라고 하기에는 거리가 좀 멀다.
- JDK 1.8부터 Collection 그리고 Array 를 Stream 으로 만들어 표준화된 방법으로 다룰수 있음.
스트림의 작업순서
1. 스트림 만들기
2. 중간연산은 N번
: 중간연산이란? 연산결과가 스트림. 반복 적용 가능능
3. 최종연산은 1번
: 최종연산이란? 연산결과가 스트림이 아닌 연산이므로 단 한번만 적용 가능. (스트림의 요소를 소모)
스트림의 특징
- Stream 은 오직 ReadOnly 이다. (원본을 변경하지 않음)
- 1회용이다. 최종연산을 하면 요소가 소모 되다보니 필요하면 다시 스트림을 생성해야 한다.
- 지연 연산
: 최종 연산 전까지 중간연산이 수행되지 않는다.
- 병렬로 처리
: 멀티스레드 사용
: 디폴트 값은 직렬 sequential()
: 병렬 처리를 원한다면 키워드 병렬 parallel() 사용.
- 기본형 스트림
: 오토박싱&언박싱의 비효율의 제거하기 위함
: 데이터소스가 Primitive Type 일 경우에만 사용가능하다.
: IntStream, LongStream, DoubleStream
연습
Collection 스트림 만들기
Collection Interface 에는 stream() 메소드가 존재한다.
그러므로 Collection Interface 자손인 List / Set 은 steam() 을 사용할 수 있다.
// 리스트 초기화
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// 리스트를 Stream 으로 반환
Stream<Integer> intStream = list.stream();
// (1) Stream 의 모든 요소 출력
intStream.forEach(System.out::println); // 메서드 참조
// (2) Stream 의 모든 요소 출력
// intStream.forEach(i -> System.out.println(i)); // 람다식
//== 주석 이유: 스트림의 최종연산(forEach)으로 스트림이 닫혀, 재호출 시 에러 발생.
Array 스트림 만들기
// String 배열 Stream 초기화
Stream<String> strStream1 = Stream.of("a", "b", "c");
Stream<String> strStream2 = Stream.of(new String[] {"a", "b", "c"});
Stream<String> strStream3 = Arrays.stream(new String[] {"a", "b", "c"});
// Integer 배열 Stream
Stream<Integer> intStream = Arrays.stream(new Integer[] {1, 2, 3, 4, 5});
// int 배열 Stream (기본타입에는 최종연산 count() / sum() / average() 등 제공.)
IntStream intStream1 = Arrays.stream(new int[] {1, 2, 3, 4, 5});
Random 스트림 만들기
// Random Stream 초기화
IntStream randomStream2 = new Random().ints(); // 무한 스트림
IntStream randomStream2 = new Random().ints(8); // 1 2 3 4 5 6 7 8
IntStream randomStream3 = IntStream.range(1, 8); // 1 2 3 4 5 6 7
IntStream randomStream4 = IntStream.rangeClosed(1, 8); // 1 2 3 4 5 6 7 8
무한 스트림 만들기
// 초기(seed)값 0을 시작으로 짝수 람다식을 사용해 무한스트림
Stream<Integer> evenStream = Stream.iterate(0, n->n+2);
// generate 는 seed 값을 사용하지 않는다.
Stream<Double> randomStream = Stream.generate(Math::random); // 랜덤값 계속 출력
Stream<Integer> oneStream = Stream.generate(() -> 1); // 1 계속 출력
iterate(T seed, UnaryOperator f)
iterate 의 매개변수 UnaryOperator 는 단항 연산자로 1개의 입력으로 1개의 출력이 나옴
generate(Supplier s)
generate 의 매개변수 Supplier 는 입력이 없고 출력만 있는 함수형 인터페이스(FunctionalInterface)
빈 스트림 만들기
Stream emptyStream = Stream.empty();
스트림의 중간 연산
중간연산의 종류는 다음과 같다.
- skip, limit, distinct, filter 연습
/* skip 과 limit 연습 */
IntStream intStream1 = IntStream.rangeClosed(1, 10); // 1 2 3 4 5 6 7 8 9 10
intStream1.skip(3).limit(5).forEach(System.out::print); // 4 5 6 7 8
/* distinct 연습 */
IntStream intStream2 = IntStream.of(1, 1, 2, 2, 3, 3); // 1 1 2 2 3 3
intStream2.distinct().forEach(System.out::print); // 1 2 3
/* filter 연습 */
IntStream intStream3 = IntStream.rangeClosed(1, 10); // 1 2 3 4 5 6 7 8 9 10
intStream3.filter(i -> i%2==0)
.forEach(System.out::print); // 2 4 6 8 10
IntStream intStream4 = IntStream.rangeClosed(1, 10); // 1 2 3 4 5 6 7 8 9 10
intStream4.filter(i -> i%2!=0 && i%3!=0)
.forEach(System.out::print); // 1 5 7
IntStream intStream5 = IntStream.rangeClosed(1, 10); // 1 2 3 4 5 6 7 8 9 10
intStream5.filter(i -> i%2!=0)
.filter(i -> i%3!=0)
.forEach(System.out::print); // 1 5 7
- sort 연습
// 기본정렬-1 (대소문자 구별O)
Stream<String> strStream1 = Stream.of("a", "b", "B", "b", "C", "d", "e");
strStream1
.sorted()
.forEach(System.out::print); // B C a b b d e
// 기본정렬-2
Stream<String> strStream2 = Stream.of("a", "b", "B", "b", "C", "d", "e");
strStream2
.sorted(Comparator.naturalOrder())
.forEach(System.out::print); // B C a b b d e
// 기본정렬-3 (람다식 사용)
Stream<String> strStream3 = Stream.of("a", "b", "B", "b", "C", "d", "e");
strStream3
.sorted((s1, s2) -> s1.compareTo(s2))
.forEach(System.out::print); // B C a b b d e
// 기본정렬-4 (메서드참조 사용)
Stream<String> strStream4 = Stream.of("a", "b", "B", "b", "C", "d", "e");
strStream4
.sorted(String::compareTo)
.forEach(System.out::print); // B C a b b d e
// 역순정렬-1
Stream<String> strStream5 = Stream.of("a", "b", "B", "b", "C", "d", "e");
strStream5
.sorted(Comparator.reverseOrder())
.forEach(System.out::print); // e d b b a C B
// 역순정렬-2
Stream<String> strStream6 = Stream.of("a", "b", "B", "b", "C", "d", "e");
strStream6
.sorted(Comparator.<String>naturalOrder().reversed())
.forEach(System.out::print); // e d b b a C B
// 대소문자 구별하지 않고 정렬하기
Stream<String> strStream7 = Stream.of("a", "b", "B", "b", "C", "d", "e");
strStream7
.sorted(String.CASE_INSENSITIVE_ORDER)
.forEach(System.out::print); // a b B b C d e
// 대소문자 구별하지 않고 역순으로 정렬하기
Stream<String> strStream8 = Stream.of("a", "b", "B", "b", "C", "d", "e");
strStream8
.sorted(String.CASE_INSENSITIVE_ORDER.reversed())
.forEach(System.out::print); // e d C b B b a
// 스트링 길이로 정렬하기
Stream<String> strStream9 = Stream.of("a", "b", "B", "b", "C", "d", "e");
strStream9
.sorted(Comparator.comparing(String::length))
.forEach(System.out::print); // e d C b B b a
- map 연습
File[] fileArr = {
new File("Ex1.java"),
new File("Ex2.bak"),
new File("Ex3.java"),
new File("Ex4"),
new File("Ex5.txt")};
// Stream<File> 생성
Stream<File> fileStream1 = Stream.of(fileArr);
// Stream<File> -> Stream<String> 으로 변환
Stream<String> fileName1 = fileStream1.map(File::getName);
// 출력
fileName1.forEach(System.out::println);
/**
* 출력 결과
* -------------
* Ex1.java
* Ex2.bak
* Ex3.java
* Ex4
* Ex5.txt
* -------------
*/
- peek 연습
File[] fileArr = {
new File("Ex1.java"),
new File("Ex2.bak"),
new File("Ex3.java"),
new File("Ex4"),
new File("Ex5.txt")};
// Stream<File> 생성
Stream<File> fileStream2 = Stream.of(fileArr);
fileStream2
.map(f -> f.getName()) // 파일명 추출
.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::println); // 최종연산 - 출력
/*
* 출력 결과
* -------------
* [디버깅] filename=Ex1.java
* [디버깅] extension=java
* JAVA
* [디버깅] filename=Ex2.bak
* [디버깅] extension=bak
* BAK
* [디버깅] filename=Ex3.java
* [디버깅] extension=java
* [디버깅] filename=Ex5.txt
* [디버깅] extension=txt
* TXT
* -------------
*/
- flatmap 연습
// 여러개의 스트림을 하나의 스트림에 넣기 (map)
Stream<String[]> strArrStream1 = Stream.of(
new String[] {"abc", "def", "ghi"} ,
new String[] {"ABC", "def", "jkl"}
);
Stream<Stream<String>> strStreamStream = strArrStream1.map(Arrays::stream);
strStreamStream
.forEach(System.out::println);
/**
* 출력결과
* -------------------
* java.util.stream.ReferencePipeline$Head@3b9a45b3
* java.util.stream.ReferencePipeline$Head@7699a589
* ------------------
*/
// 하나의 스트림으로 합치기 (flatMap)
Stream<String[]> strArrStream2 = Stream.of(
new String[] {"abc", "def", "ghi"} ,
new String[] {"ABC", "def", "jkl"}
);
Stream<String> strStream = strArrStream2.flatMap(Arrays::stream);
strStream
.forEach(System.out::println);
/**
* 출력결과
* -------------------
* abc
* def
* ghi
* ABC
* def
* jkl
* ------------------
*/
// 하나의 스트림으로 합치기 (flatMap)
String[] lineArr = {
"Believe or not It is true",
"Do or do not There is no try"
};
Stream<String> lineStream = Arrays.stream(lineArr);
lineStream.flatMap(l -> Stream.of(l.split(" +")))
.map(String::toLowerCase)
.forEach(System.out::println);
/**
* 출력결과
* -------------------
* believe
* or
* not
* it
* is
* true
* do
* or
* do
* not
* there
* is
* no
* try
* ------------------
*/
스트림의 최종 연산
최종연산의 종류는 다음과 같다.
- forEachOrdered 연습
// 병렬 처리 시, 순서 보장이 안됨
IntStream
.range(1, 10)
.parallel()
.forEach(System.out::print); // 652178943
// 병렬 처리 시, 순서 보장을 위해 forEachOrdered 사용
IntStream
.range(1, 10)
.parallel()
.forEachOrdered(System.out::print); // 123456789
- 조건 검사 allMatch(), anyMatch(), noneMatch() 연습
// allMatch 은 모든 요소가 조건을 만족해야만 바로 true 반환
boolean all = IntStream.range(1, 10)
.peek(s -> System.out.printf("[디버깅] 로그=%s%n", s))
.allMatch(i -> i <= 5);
System.out.println(all); // false
// anyMatch 은 한 요소라도 조건을 만족하다면 바로 true 반환
boolean any = IntStream.range(1, 10)
.peek(s -> System.out.printf("[디버깅] 로그=%s%n", s))
.anyMatch(i -> i <= 5);
System.out.println(any); // true
// noneMatch 은 모든 요소가 조건을 만족시키지 않으면 바로 true 반환
boolean none = IntStream.range(1, 10)
.peek(s -> System.out.printf("[디버깅] 로그=%s%n", s))
.noneMatch(i -> i <= 5);
System.out.println(any); // true
/**
* 출력결과
* --------------
* [디버깅] 로그=1
* [디버깅] 로그=2
* [디버깅] 로그=3
* [디버깅] 로그=4
* [디버깅] 로그=5
* [디버깅] 로그=6
* false
* [디버깅] 로그=1
* true
* [디버깅] 로그=1
* true
* -------------
*/
- 조건에 일치하는 요소 찾기 findFirst(), findAny() 연습
String[] strArr = {
"Inheritance", "Java", "Lambda", "stream",
"OptionalDouble", "IntStream", "count", "sum"
};
// findFirst 는 첫 번째 요소를 반환
Optional<String> first = Stream.of(strArr)
.parallel()
.peek(s -> System.out.printf("[디버깅] 로그=%s%n", s))
.filter(s -> s.charAt(0) == 's')
.findFirst();
System.out.println(first.get()); // stream 또는 sum (병렬이기에 출력이 매번 다름)
// findAny 는 아무거나 하나 반환
Optional<String> any = Stream.of(strArr)
.peek(s -> System.out.printf("[디버깅] 로그=%s%n", s))
.filter(s -> s.charAt(0) == 's')
.findAny();
System.out.println(any.get()); // stream
/**
* 출력결과
* --------------
* [디버깅] 로그=IntStream
* [디버깅] 로그=Inheritance
* [디버깅] 로그=OptionalDouble
* [디버깅] 로그=stream
* [디버깅] 로그=Java
* [디버깅] 로그=Lambda
* [디버깅] 로그=sum
* [디버깅] 로그=count
* sum
* [디버깅] 로그=Inheritance
* [디버깅] 로그=Java
* [디버깅] 로그=Lambda
* [디버깅] 로그=stream
* stream
* -------------
*/
- 스트림의 요소를 하나씩 줄여가며 누적연산 수행 reduce() 연습
: identity 는 초기값
: accumulator 는 이전 연산결과와 스트림의 요소에 수행할 연산
: combiner 은 병렬처리된 결과를 합치는데 사용할 연산(병렬 스트림)
String[] strArr = {
"Inheritance", "Java", "Lambda", "stream",
"OptionalDouble", "IntStream", "count", "sum"
};
// Stream<String> -> Stream<Integer> 변환
Stream<Integer> integerStream = Stream.of(strArr).map(String::length);
// Stream<String> -> IntStream 변환
IntStream intStream = Stream.of(strArr).mapToInt(String::length);
// 카운터 구하기
int count = intStream.reduce(0, (a, b) -> a+1);
// 총 합 구하기
int sum = integerStream.reduce(0, (a, b) -> a+ b);
// 최대 값 구하기
OptionalInt max = Stream.of(strArr)
.mapToInt(String::length)
.reduce(Integer::max);
// 최소 값 구하기
OptionalInt min = Stream.of(strArr)
.mapToInt(String::length)
.reduce(Integer::min);
System.out.println(count); // 8 (스트림 개수)
System.out.println(sum); // 58 (문자의 총 길이 합)
System.out.println(max.getAsInt()); // 14
System.out.println(min.getAsInt()); // 3
- collect() 와 Collectors 연습
: collect()는 Collector를 매개변수로 하는 스트림의 최종연산
: Collector는 collect에 필요한 메서드를 정의 해놓은 인터페이스
: Collectors는 Collector 인터페이스를 구현 클래스 (다양한 기능 제공)
: collect() 메서드는... 5개의 매개변수가 들어가지만 친절하게도 모두 구현되어 있어서 Collector 하나만 이용하면 된다.
// 객체 생성
Student student1 = new Student("준");
Student student2 = new Student("상");
// 리스트 만들기
List<Student> student = new ArrayList<>();
student.add(student1);
student.add(student2);
// Stream<Student> 로 초기화
Stream<Student> studentStream = student.stream();
// List 로 변환 [Stream<Student> -> List<String>] 변환
List<String> names1 =
student.stream()
.map(Student::getName) // 이름만 추출
.collect(Collectors.toList()); // 리스트로 변환
// ArrayList 로 변환
List<String> names2 =
// studentStream
student.stream()
.map(Student::getName)
.collect(Collectors.toCollection(ArrayList::new)); // ArrayList로 변환
// Array 로 변환 - 매개변수에 꼭 변환 타입을 적어줘야한다.
Student[] studentArr1 =
student.stream()
.toArray(Student[]::new);
// Array 로 변환 - 매개변수가 없다면, 무조건 Object[] 타입이다.
Object[] studentArr2 =
student.stream()
.toArray();
// 카운트
long count1 = student.stream().count(); // 전체 count
long count2 = student.stream().collect(Collectors.counting()); // 그룹별 count
// 접수 합계
long totScore1 = student.stream().mapToInt(Student::getScore).sum();
long totScore2 = student.stream().collect(Collectors.summingInt(Student::getScore));
// reducing - 스트림을 리듀싱
// joining - 문자열 스트림의 요소를 모두 연결
String student3 = student.stream()
.map(Student::getName)
.collect(Collectors.joining());
String student4 = student.stream()
.map(Student::getName)
.collect(Collectors.joining(","));
String student5 = student.stream()
.map(Student::getName)
.collect(Collectors.joining(",", "*", "%"));
System.out.println(names1); // [준, 상]
System.out.println(names2); // [준, 상]
System.out.println(count1); // 2
System.out.println(count2); // 2
System.out.println(totScore1); // 0
System.out.println(totScore2); // 0
System.out.println(student3); // 준상
System.out.println(student4); // 준,상
System.out.println(student5); // *준,상%
- partitioningBy() / groupingBy() 연습
import java.util.*;
import java.util.stream.Collectors;
import static java.util.Comparator.comparingInt;
import static java.util.stream.Collectors.*;
public class Example {
public static void main(String[] args) {
/**
* partitioningBy()
*
* - 스트림을 2분할
*/
Student student1 = new Student("네오", "남", 150, "1", "A");
Student student2 = new Student("프로도", "여", 140, "1", "B");
Student student3 = new Student("콘", "남", 130, "1", "C");
Student student4 = new Student("어피치", "여", 120, "1", "D");
Student student5 = new Student("죠르디", "남", 110, "1", "A");
Student student6 = new Student("앙몬드", "여", 100, "1", "B");
Student student7 = new Student("라이언", "남", 90, "1", "C");
Student student8 = new Student("스카피", "여", 80, "1", "D");
Student student9 = new Student("무지", "남", 70, "1", "A");
List<Student> studentList = new ArrayList<>();
studentList.add(student1);
studentList.add(student2);
studentList.add(student3);
studentList.add(student4);
studentList.add(student5);
studentList.add(student6);
studentList.add(student7);
studentList.add(student8);
studentList.add(student9);
//======= (1) 학생들을 성별로 2분할(남/녀)
Map<Boolean, List<Student>> studentA = studentList
.stream()
.collect(Collectors.partitioningBy(Student::isMale));
System.out.println("=======================");
List<Student> maleStudent = studentA.get(true); // 남학생 List
maleStudent.stream().forEach(System.out::println);
List<Student> femaleStudent = studentA.get(false); // 여학생 List
femaleStudent.stream().forEach(System.out::println);
//======= (2) 학생들을 성별로 2분할(남/녀)로 나눈 후, 카운팅
Map<Boolean, Long> studentB = studentList
.stream()
.collect(Collectors.partitioningBy(Student::isMale, Collectors.counting()));
System.out.println("=======================");
Long maleStudentCnt = studentB.get(true); // 남학생 수
System.out.println(maleStudentCnt);
Long femaleStudentCnt = studentB.get(false); // 여학생 수
System.out.println(femaleStudentCnt);
//======= (3) 학생들을 성별로 2분할(남/녀)로 나눈 후, 1등 뽑기
Map<Boolean, Optional<Student>> studentC = studentList
.stream()
.collect(Collectors.partitioningBy(Student::isMale,
Collectors.maxBy(comparingInt(Student::getScore))));
System.out.println("=======================");
Optional<Student> maleStudentFirst = studentC.get(true);
System.out.println(maleStudentFirst.get()); // 남학생 1등
System.out.println(maleStudentFirst.get()); // 남학생 1등 (Optional 꺼내기)
Optional<Student> femaleStudentFirst = studentC.get(false);
System.out.println(femaleStudentFirst); // 여학생 1등
System.out.println(femaleStudentFirst.get()); // 여학생 1등 (Optional 꺼내기)
//======= (4) 학생들을 성별로 2분할(남/녀)로 나눈 후, 다시 2분할(성적)으로 나눔
Map<Boolean, Map<Boolean, List<Student>>> studentD = studentList
.stream()
.collect(Collectors.partitioningBy(Student::isMale,
Collectors.partitioningBy(s -> s.getScore() < 80)));
System.out.println("=======================");
List<Student> failMaleStudent = studentD.get(true).get(true); // 불합격 남학생
System.out.println(failMaleStudent);
List<Student> failfemaleStudent = studentD.get(false).get(true); // 불합격 여학생
System.out.println(failfemaleStudent);
/**
* groupingBy()
*
* - 스트림을 N분할
*/
//======= (1) 반별로 그룹화
Map<String, List<Student>> studentE = studentList
.stream()
.collect(groupingBy(Student::getBan));
System.out.println("=======================");
for(List<Student > ban : studentE.values()) {
for(Student studentDetail : ban) {
System.out.println(studentDetail);
}
}
//======= (2) 성적별로 그룹화
Map<Object, List<Student>> studentF = studentList
.stream()
.collect(groupingBy(s -> {
if (s.getScore() >= 150)
return s.grade = "우수";
else if (s.getScore() >= 100)
return s.grade = "보통";
else
return s.grade = "미달";
}));
System.out.println("=======================");
TreeSet keySet = new TreeSet(studentF.keySet());
for(Object key : keySet) {
System.out.println("[" + key + "]");
for(Student studentDetail : studentF.get(key)) {
System.out.println(studentDetail);
}
}
//======= (3) 성적별 학생수 ??
Map<Object, Long> studentG = studentList
.stream()
.collect(groupingBy(s -> {
if (s.getScore() >= 150)
return "우수";
else if (s.getScore() >= 100)
return "보통";
else
return "미달";
}, Collectors.counting()));
System.out.println("=======================");
for(Object key : studentG.keySet()) {
System.out.printf("[%s] - %s명\n", key, studentG.get(key));
}
//======= (4) 다중 그룹화 (학년별 / 반별 1등)
Map<String, Map<String, Student>> studentI = studentList
.stream()
.collect(groupingBy(Student::getBan,
groupingBy(Student::getHak,
collectingAndThen(
maxBy(comparingInt(Student::getScore))
, Optional::get
)
)
));
System.out.println("=======================");
for(Map<String, Student> ban : studentI.values()) {
for(Student s : ban.values()) {
System.out.println(s);
}
}
}
/**
* 출력결과
*
* =======================
* Student{name='네오', sex='남', score=150, ban='A', grade='null'}
* Student{name='콘', sex='남', score=130, ban='C', grade='null'}
* Student{name='죠르디', sex='남', score=110, ban='A', grade='null'}
* Student{name='라이언', sex='남', score=90, ban='C', grade='null'}
* Student{name='무지', sex='남', score=70, ban='A', grade='null'}
* Student{name='프로도', sex='여', score=140, ban='B', grade='null'}
* Student{name='어피치', sex='여', score=120, ban='D', grade='null'}
* Student{name='앙몬드', sex='여', score=100, ban='B', grade='null'}
* Student{name='스카피', sex='여', score=80, ban='D', grade='null'}
* =======================
* 5
* 4
* =======================
* Student{name='네오', sex='남', score=150, ban='A', grade='null'}
* Student{name='네오', sex='남', score=150, ban='A', grade='null'}
* Optional[Student{name='프로도', sex='여', score=140, ban='B', grade='null'}]
* Student{name='프로도', sex='여', score=140, ban='B', grade='null'}
* =======================
* [Student{name='무지', sex='남', score=70, ban='A', grade='null'}]
* []
* =======================
* Student{name='네오', sex='남', score=150, ban='A', grade='null'}
* Student{name='죠르디', sex='남', score=110, ban='A', grade='null'}
* Student{name='무지', sex='남', score=70, ban='A', grade='null'}
* Student{name='프로도', sex='여', score=140, ban='B', grade='null'}
* Student{name='앙몬드', sex='여', score=100, ban='B', grade='null'}
* Student{name='콘', sex='남', score=130, ban='C', grade='null'}
* Student{name='라이언', sex='남', score=90, ban='C', grade='null'}
* Student{name='어피치', sex='여', score=120, ban='D', grade='null'}
* Student{name='스카피', sex='여', score=80, ban='D', grade='null'}
* =======================
* [미달]
* Student{name='라이언', sex='남', score=90, ban='C', grade='미달'}
* Student{name='스카피', sex='여', score=80, ban='D', grade='미달'}
* Student{name='무지', sex='남', score=70, ban='A', grade='미달'}
* [보통]
* Student{name='프로도', sex='여', score=140, ban='B', grade='보통'}
* Student{name='콘', sex='남', score=130, ban='C', grade='보통'}
* Student{name='어피치', sex='여', score=120, ban='D', grade='보통'}
* Student{name='죠르디', sex='남', score=110, ban='A', grade='보통'}
* Student{name='앙몬드', sex='여', score=100, ban='B', grade='보통'}
* [우수]
* Student{name='네오', sex='남', score=150, ban='A', grade='우수'}
* =======================
* [우수] - 1명
* [미달] - 3명
* [보통] - 5명
* =======================
* Student{name='네오', sex='남', score=150, ban='A', grade='우수'}
* Student{name='프로도', sex='여', score=140, ban='B', grade='보통'}
* Student{name='콘', sex='남', score=130, ban='C', grade='보통'}
* Student{name='어피치', sex='여', score=120, ban='D', grade='보통'}
*/
}
class Student {
String name;
String sex;
int score;
String hak;
String ban;
String grade;
public Student(String name, String sex, int score, String hak, String ban) {
this.name = name;
this.sex = sex;
this.score = score;
this.hak = hak;
this.ban = ban;
}
public boolean isMale() {
if (this.sex.equals("남"))
return true;
return false;
}
public void setGrade(String grade) {
this.grade = grade;
}
public String getHak() { return hak; }
public String getBan() { return ban; }
public String getName() { return name;}
public int getScore() { return score; }
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", score=" + score +
", ban='" + ban + '\'' +
", grade='" + grade + '\'' +
'}';
}
}
'Java' 카테고리의 다른 글
[Java] 쓰레드(Thread) 란? 특징과 사용법 (0) | 2021.05.04 |
---|---|
[Java] 예외처리(Exception) 란? - 특징과 사용법 (0) | 2021.04.25 |
[Java] Java8 에 새롭게 추가된 기능을 알아보자 (0) | 2021.04.12 |
[Java] 리플렉션(Reflection) 이란? (0) | 2021.03.10 |
[Java] Collection Hierarchy (0) | 2020.08.28 |