Java

Java 기초(Generics, lambda)- AWS 풀스택 과정 54일차

awspspgh 2024. 10. 11. 18:23
목차
1. 실습
2. Generics
3. lambda

 

1. 실습

▣ Menu

package sale;

import java.util.Objects;

public class Menu {
	private int  menuId; // 기본키 역할
	private String menuName;
	private int price;
	
	public Menu() {}
	
	// equals용 생성자
	public Menu(int id) {
		this.menuId = id;
	}
	
	public Menu(int id, String menuName, int price) {
		menuId = id;
		this.menuName = menuName;
		this.price = price;
	}
	
	@Override
	public String toString() {
		return  menuId + "." + menuName + " : " + price + "원";
	}
	public int getMenuId() {
		return menuId;
	}
	public void setMenuId(int menuId) {
		this.menuId = menuId;
	}
	public String getMenuName() {
		return menuName;
	}
	public void setMenuName(String menuName) {
		this.menuName = menuName;
	}
	public int getPrice() {
		return price;
	}
	public void setPrice(int price) {
		this.price = price;
	}

	@Override
	public int hashCode() {
		return Objects.hash(menuId, menuName, price);
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Menu other = (Menu) obj;
		return menuId == other.menuId; // id만 일치해도 true
	}
	
}

 

▣ Order

package sale;

public class Order extends Menu{
	
	private int orderNum;
	private int cnt;
	private int totalPrice;
	
	public Order() {}
	public Order(int id, String name, int price, int cnt, int orderNum) {
		super(id, name, price);
		this.orderNum = orderNum;
		this.cnt = cnt;
		this.totalPrice = cnt * price;
	}
	
	// 출력메서드, super.toString(); // 부모의 toString 호출
	public void orderPrint() {
		System.out.println(super.toString()+"/");
		System.out.println(cnt+"개 주문 => 금액 : " + totalPrice);
	}
	
	@Override
	public String toString() {
		return "orderNum=" + orderNum + super.toString() + ", cnt=" + cnt + ", totalPrice=" + totalPrice;
	}
	
	// getter & setter
	public int getOrderNum() {
		return orderNum;
	}
	public void setOrderNum(int orderNum) {
		this.orderNum = orderNum;
	}
	public int getCnt() {
		return cnt;
	}
	public void setCnt(int cnt) {
		this.cnt = cnt;
	}
	public int getTotalPrice() {
		return totalPrice;
	}
	public void setTotalPrice(int totalPrice) {
		this.totalPrice = totalPrice;
	}
}

 

▣ SaleMain

package sale;

import java.util.Scanner;

public class SaleMain {

	public static void main(String[] args) {
		// 키오스크
		/* menu
		 * 1.메뉴추가|2.메뉴삭제|3.메뉴수정(가격수정)
		 * 4.메뉴보기(전체메뉴보기)|5.주문|6.주문내역출력(영수증)
		 * 7.전체판매내역|8.종료
		 * 
		 * Menu Class 생성 => 메뉴 1개에 대한 정보
		 * 제품ID
		 * 제품명
		 * 가격
		 * 
		 * 1. 관리자 제품에 대한 정보를 입력
		 * 2. 주문자가 제품을 주문 (제품ID, 수량)
		 * 3. 주문ID에 해당하는 Menu를 찾아서 이름과 가격을 가져오기
		 * 4. Order 클래스에 제품ID, 제품명, 수량, 가격, 수량*가격 저장
		 * 
		 * Order Class 생성 menu 상속 => 한 주문에 대한 정보
		 * 주문번호
		 * 제품ID
		 * 제품명
		 * 수량
		 * 가격
		 * 금액
		 * 
		 * SaleController
		 * Menu List => List<Menu> menu = new ArrayList<>();
		 * OrderList => List<Order> order = new ArrayList<>();
		 */
		
		SaleController sc = new SaleController();
		Scanner scan = new Scanner(System.in);
		// 미리 몇 가지 메뉴 추가 메서드 호출
		sc.addMenu();
		
		int menu = 0;
		
		do {
			System.out.println("1.메뉴추가|2.메뉴삭제|3.메뉴수정(가격수정)|7.전체판매내역");
			System.out.println("4.메뉴보기(전체메뉴보기)|5.주문|6.주문내역출력(영수증)");
			System.out.println("8.종료");
			System.out.println("menu >");
			menu = scan.nextInt();
			
			switch(menu) {
			case 1:
				sc.add(scan);
				break;
			case 2:
				sc.delete(scan);
				break;
			case 3:
				sc.update(scan);
				break;
			case 4:
				sc.printMenu();
				break;
			case 5:
				sc.orderPick(scan);
				break;
			case 6:
				sc.orderPrint(scan);
				break;
			case 7:
				sc.totalOrderPrint();
				break;
			case 8:
				System.out.println("키오스크를 종료합니다.");
				break;
			default:
				System.out.println("잘못된 메뉴입니다.");
			}
		}while(menu != 8);
		
		scan.close();
		
	}

}

 

▣ SaleController

package sale;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class SaleController {
	
	private int orderNum;
	private int menuId;
	private int orderListindex;
	private int totalSum;
	
	private List<Menu> menu = new ArrayList<>();
//	private List<Order> order = new ArrayList<>();
	private List<OrderList> orderList = new ArrayList<>();
	
	public void addMenu() {
		// 기본 메뉴 추가 메서드
		menu.add(new Menu(++menuId,"김치찌개",9000));
		menu.add(new Menu(++menuId,"된장찌개",9000));
		menu.add(new Menu(++menuId,"순두부찌개",9000));
		menu.add(new Menu(++menuId,"제육볶음",10000));
		menu.add(new Menu(++menuId,"오징어볶음",10000));
		
	}
	public void add(Scanner scan) {
		// 메뉴추가
		this.menuId++;
		System.out.println("메뉴명 / 가격 >");
		String menu = scan.next();
		int price = scan.nextInt();
		this.menu.add(new Menu(menuId, menu, price));
		System.out.println("추가완료!!");
	}
	public void delete(Scanner scan) {
		// 메뉴삭제 : remove(index), 
		// remove(object) : 하나의 객체 요소로 그 객체가 전체 일치라고 볼수 없음. 
		// equals 명령어 자체를 수정하면 가능.
		System.out.println("삭제할 메뉴 번호 >");
		int delMenu = scan.nextInt();
		boolean ok = menu.remove(new Menu(delMenu));
		if(ok) {
			System.out.println("삭제완료");
		}else {
			System.out.println("찾는 메뉴가 없습니다.");
		}
		for(int i=0; i<menu.size(); i++) {
			if(menu.get(i).getMenuId() == delMenu) {
				menu.remove(i); //index로 삭제
				//menu.remove(menu.get(i)); //object로 지우기
				System.out.println("삭제완료");
				return;
			}
		}
		System.out.println("찾는메뉴가 없습니다.");
		
		
	}
	public void update(Scanner scan) {
		// 메뉴 수정 : remove => add / set(index, object)
		System.out.println("수정할 메뉴 번호 >");
		int modMenu = scan.nextInt();
		System.out.println("수정가격>");
		int modPrice = scan.nextInt();
		for(int i=0; i<menu.size(); i++) {
			if(menu.get(i).getMenuId() == modMenu) {
				menu.get(i).setPrice(modPrice); //해당 객체의 가격만 수정
				System.out.println("수정완료");
				return;
			}
		}
		System.out.println("찾는메뉴가 없습니다.");
	}
	public void printMenu() {
		// 전체 메뉴 출력 메서드
		System.out.println("--menu--");
		for(Menu m : menu) {
			System.out.println(m);
		}
		System.out.println("---------");
	}
	public void orderPick(Scanner scan) {
		// 주문
		// 메뉴번호와 수량을 입력받아 / order 객체를 생성 후 / orderLsit 추가
		// order 객체를 생성 필요한 메뉴명, 가격 menuList 찾아와야 함.
		
		this.orderList.add(new OrderList((orderListindex+1))); //가장 마지막에 
		int or =-1;
		do{
			
		
		System.out.println("주문메뉴번호 >");
		int pickMenu = scan.nextInt();
		System.out.println("수량 >");
		int count = scan.nextInt();
		
		Menu pick = null;
		
		for(int i=0; i<menu.size(); i++) {
			if(menu.get(i).getMenuId() == pickMenu) {
				// 주문한 메뉴명과 가격을 리턴
				pick = menu.get(i);
				break;
			}
		}
		
		if(pick == null) {
			System.out.println("주문번호가 없습니다.");
			return;
		}
		
		this.orderNum++;
		
		Order order = new Order(pickMenu, pick.getMenuName(), 
				pick.getPrice(), count, orderNum);
		
		this.orderList.get(orderListindex).addOrder(order);
		
		System.out.println("주문여부(1/0) >");
		 or = scan.nextInt();
		
		}while(or == 1);
				
		orderListindex++;
		System.out.println("주문완료~!!");
	}
	public void orderPrint(Scanner scan) {
		// 주문 출력
		int sum = 0;
		System.out.println("--주문내역--");
		for(Order o : orderList.get(orderListindex-1).getOrder()) {
			sum+= o.getTotalPrice();
			o.orderPrint();
		}
		totalSum += sum;
		
		System.out.println("----------");
		System.out.println("총지불금액 : "+sum);
		
	}
	public void totalOrderPrint() {
		
		System.out.println("준비중입니다...");
		for(OrderList o : orderList) {
			System.out.println(o);
		}
		System.out.println("----------");
		System.out.println("총수입 : " + totalSum);
	}
}

 

▣ OrderList

package sale;

import java.util.ArrayList;
import java.util.List;

public class OrderList {
	private int orderNum;
	private List<Order> order = new ArrayList<>();
	
	
	public OrderList(int orderNum) {
		this.orderNum = orderNum;
		
	}
	public void addOrder(Order order) {
		this.order.add(order);
	}
	
	
	@Override
	public String toString() {
		return "주문 번호 : " + orderNum + ", 주문 내역 : " + order;
	}
	public int getOrderNum() {
		return orderNum;
	}
	public void setOrderNum(int orderNum) {
		this.orderNum = orderNum;
	}
	public List<Order> getOrder() {
		return order;
	}
	public void setOrder(List<Order> order) {
		this.order = order;
	}
	
	
}

 

▷ 출력

출력 (1)

 

2. Generics

▣ Generics01

package day09;

import java.util.ArrayList;
import java.util.List;

public class Generics01 {

	public static void main(String[] args) {
		/* 제너릭(Generics) : 데이터의 타입을 나중에 확정하는 기법
		 * 클래스나 메서드를 선언할 때 어떤 데이터가 올 지 확신이 없다면,
		 * 제네릭 타입으로 구현 => 나중에 객체 생성 시 타입을 확정하여 구현
		 * 
		 * 객체의 타입을 컴파일 할 때 체크할 수 있어서 안정성을 
		 * 해치지 않은 선에서 적당히 형변환이 가능한 기법
		 * 안정성 - 의도하지 않은 타입의 객체가 저장되는 것을 막는 것
		 */
		
		// 객체 구현시 타입을 적어서 처리 (안 써도 가능)
		List<Sale> list = new ArrayList<>();
		int id = 1;
		String name = "햄버거";
		int price = 5000;
		
		Sale<Integer, String> s = new Sale(id, name, price);
		list.add(s);
		list.add(new Sale(2, "콜라", 1500));
		int sum = 0;
		int idSum = 0;
		for(Sale t : list) {
			idSum += (int)t.getId();
			sum += t.getPrice();
			System.out.println(t);
		}
		
		System.out.println("id합계 : " + idSum);
		System.out.println("합계 : " + sum);

	}

}

 

▣ Sale

package day09;

public class Sale<K, V> {
	// 제너릭의 타입 값은 대문자로...
	// 멤버변수 id, menu, price
	private K id;
	private V menu;
	private int price;
	
	public Sale () {}
	
	public Sale(K id, V menu, int price) {
		this.id = id;
		this.menu = menu;
		this.price = price;
	}

	public K getId() {
		return id;
	}

	public void setId(K id) {
		this.id = id;
	}

	public V getMenu() {
		return menu;
	}

	public void setMenu(V menu) {
		this.menu = menu;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "Sale [" + id + "." + menu + " / " + price + "]";
	}

}

 

▷ 출력

출력 (1)

 

3. lambda

▣ Lambda01

package day09;

import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;

public class Lambda01 {

	public static void main(String[] args) {
		// Lambda + Stream => 람다와 스트림
		/* javascript arrowFunction(화살표 함수)와 비슷한 형태
		 * lambda : 람다식 (식을 단순하게 표현하는 방법)
		 * 	 외부 자료의 부수적인 영향(side effect)를 주지 않도록 구현하는 방법
		 * Stream : 자료의 대상과 관계없이 동일한 연산을 수행할 수 있도록 해주는 반복자
		 * - 메서드 체이닝 기법을 사용
		 * Lambda functions : 익명클래스를 사용하여 쓰는 함수
		 * 람다식의 장점 : 코드 간결성, 병렬처리가능, 불필요한 연산 최소화
		 * 단점 : 가독성이 떨어짐. 반복문 사용시 성능 저하
		 * 
		 * - 람다의 표현식
		 * const name = () => {} // javascipt  
		 * (매개변수) => {구현} // java lambda
		 * 매개변수가 1개면 () 생략가능
		 * x -> { return x+1; }
		 * (x,y) -> { return x+y }
		 * 
		 * return이 없으면 { 생략가능 }
		 * x -> x+1;
		 * x -> return x+1; // 오류
		 */
		
		List<Integer> list = new ArrayList<>();
		list.add(10);
		list.add(50);
		list.add(60);
		list.add(70);
		list.add(40);
		list.add(80);
		list.add(90);
		list.add(30);
		list.add(20);
		
		for(Integer tmp : list) {
			System.out.println(tmp);
		}
		
		System.out.println("--forEach 출력--");
		// 구현 + 실행
		list.forEach(n -> {
			System.out.print(n+" ");
		});
		
//		int sum = 0;
//		// stream을 구성 / side effect 최소화
//		list.forEach(n -> {
//			sum+=n;
//		});
		
		System.out.println();
		System.out.println("--람다함수사용 Consumer--");
		// 람다함수(익명함수) 구현 -> 실행
		Consumer<Integer> method = (n) -> {
			System.out.print(n + " ");
		};
		list.forEach(method);

		
	}

}

 

▷ 출력

출력 (1)

 

▣ Lambda02

package day09;

import java.util.HashMap;

public class Lambda02 {

	public static void main(String[] args) {
		// map을 forEach로 출력
		
		HashMap<String, Integer> map = new HashMap<>();
		map.put("hong", 82);
		map.put("kim", 68);
		map.put("lee", 96);
		map.put("park", 56);
		map.put("choi", 76);
		map.put("ha", 80);

		// Consumer : 값이 1개 / BiConsumer : 값이 2개
		map.forEach((x,y) -> {
			System.out.println(x+":"+y);
		});
		
		Number sum = (a, b) -> { // 함수 구현
			return a+b;
		};
		
		int tot = sum.add(50, 60);
		System.out.println(tot);
		
	}
	
}

// 함수형 인터페이스 생성
// 메서드가 1개여야만 함.
@FunctionalInterface
interface Number{
	int add(int a, int b);
//	int sub(int a, int b); // 메서드가 2개면 error
		}

 

▷ 출력

출력 (2)

 

▣ Stream01

package day09;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.stream.Stream;

public class Stream01 {

	public static void main(String[] args) {
		/* Stream(스트림)
		 * - 실제 입력(출력)되는 데이터의 흐름
		 * - 파이프라인으로 데이터가 흘러가능 흐름의 개념
		 * - 스트림은 자료에 스트림을 생성하여 연산(복사본)
		 * - 스티림은 연산은 연산을 다 수정하면 소모됨(1회성)
		 * - 기존 자료를 복사하여 스트림을 구성하기 때문에 
		 * 	 기존 자료의 변경을 유발하지 않음
		 * 
		 * - 스트림용 연산이 별도 존재
		 * - 중간연산, 최종연사으로 구분됨.
		 * 
		 * - 중간 연산: 메서드를 이어서 사용할 수 있음
		 * - distinct() : 중복제거 
		 *   filter() : 조건에 맞는 자료만 다음 스트림으로 이동
		 *   limit() : 스트림의 일부를 잘라냄
		 *   skip() : 스트림의 일부를 건너뜀
		 *   sorted() : 정렬 ...
		 *   map() : 새로운 형태로 변경
		 *   mapToInt() / mapToLong()
		 *   
		 * - 최종 연산 : 스트림의 최종 결과 연산 (마지막에서만 가능)
		 * 	 forEach(), count(), sum(), allMatch() : 스트림요소가 전부 일치하는지...
		 *   anyMatch() : 하나라도 일치하는지...
		 *   toArray() : 배열로 변환
		 *   collect() : 스트림 수집
		 */

		int[] arr = {1,2,3,4,5,6,7,8,9};
		// 일반적인 합계
		int sum = 0;
		for(int i : arr) {
			sum += i;
		}
		System.out.println(sum);
		System.out.println("스트림을 이용한 합계");
		
		int total = Arrays.stream(arr).sum();
		System.out.println(total);
		System.out.println("--스트림 count()--");
		// count() 연산은 return => Long
		long cnt = Arrays.stream(arr).count();
		System.out.println(cnt);
		
		// Optional : nullPointException 같은 Exception을 처리할 수 있게 도와줌
		System.out.println("-- 스트림 average() --");
		OptionalDouble avg = Arrays.stream(arr).average();
		
		System.out.println("--filter()--");
		// filter() : 조건
		// 배열의 값 중 5이상만 출력
		Arrays.stream(arr).filter(n -> n >= 5).forEach(m -> {
			System.out.print(m + " ");
		});
		
		System.out.println();
		// 5이상의 합계 출력
		int sum2 = Arrays.stream(arr).filter(n -> n >= 5).sum();
		System.out.println(sum2);
		
		int[] score = {78,89,86,58,74,51,63,89,90};
		// Stream을 이용하여 합계, 평균, 최대값
		// Stream을 이용하여 70점 이상의 인원수 출력
		
		int Sum = Arrays.stream(score).sum();
		OptionalDouble Avg = Arrays.stream(score).average();
		OptionalInt max = Arrays.stream(score).max();
		System.out.println(Sum + " : " + Avg + " : " + max);
		
		Arrays.stream(score).filter(n -> n >= 70).forEach(m -> {
			System.out.println(m + " ");
		});
		System.out.println();
		
		ArrayList<Integer> list = new ArrayList<>();
		list.add(1);
		list.add(5);
		list.add(3);
		list.add(1);
		list.add(2);
		list.add(4);
		list.add(4);
		list.add(1);
		list.add(5);
		list.add(1);
		list.add(4);
		
		System.out.println("--list stream 구성--");
		list.stream().forEach(n->{System.out.print(n+" ");});
		System.out.println();
		
		System.out.println("--distinct() 중복제거--");
		list.stream().distinct().forEach(n -> System.out.print(n + " "));
		System.out.println();
		
		System.out.println("--sorted() 정렬--");
		list.stream().distinct().sorted().forEach(n -> System.out.print(n + " "));
		System.out.println();
		
		// 합계 > intStream에게만 존재
//		int s = list.stream().sum();
		// map : 스트림 변환에 사용하는 중간연산
		// mapToInt : map 값을 int로 변환하는 역할
		int s = list.stream().mapToInt(n -> n.intValue()).sum();
		System.out.println(s);
		
		// 스트림 객체 생성
		System.out.println("--Stream 객체 생성--");
		Stream<Integer> s1 = Stream.of(10,20,30,40,50,60);
		
		int s2 = s1.mapToInt(n -> n.intValue()).sum();
		System.out.println(s2);
		
		// 이미 소모된 스트림은 다시 사용할 수 없음
//		OptionalDouble avg3 = s1.mapToInt(n -> n.intValue()).average();
//		System.out.println(avg3);
		
	}

}

 

▷ 출력

출력 (3)

 

▣ Stream02

package day09;

import java.util.Arrays;

public class Stream02 {

	public static void main(String[] args) {
		/* 배열에서 짝수만 출력(정렬) 중복되는 값이 있다면 제거
		 */

		int[] arr = {1,8,5,4,9,6,3,1,2,4,7,8,5,7};
		
		Arrays.stream(arr).distinct().sorted().filter(n -> n % 2 == 0).forEach(m -> System.out.print(m + " "));
	
		// 배열로 리턴
		int[] result = Arrays.stream(arr).filter(n -> n%2 == 1).distinct().sorted().toArray();
		for(int tmp : result) {
			System.out.println(tmp);
		}
	
	
	}

}

 

▷ 출력

출력 (4)

 

▣ Stream03

package day09;

import java.util.ArrayList;
import java.util.Comparator;

public class Stream03 {

	public static void main(String[] args) {
		/* Student 클래스로 리스트 구성
		 * Student 이름, 점수만 가지는 클래스
		 * 
		 * 학생 5명을 추가하고, 콘솔에 출력
		 * 홍길동 : 80
		 */

		ArrayList<Student> list = new ArrayList<>();
		list.add(new Student("hong", 89));
		list.add(new Student("kim", 79));
		list.add(new Student("lee", 74));
		list.add(new Student("park", 95));
		list.add(new Student("choi", 78));
		
		// 스트림을 이용하여 콘솔에 출력
		list.stream().forEach(n -> {
			String name = n.getName();
			int score = n.getScore();
			System.out.println(name + "=>" + score);
		});
		
		// list의 점수 합계 / 전체 인원수
		int sum = list.stream().mapToInt(n -> n.getScore()).sum();
		long cnt = list.stream().count();
		System.out.println("점수합계 : " + sum + " 인원수 : " + cnt);
		
		System.out.println("-----------");
		// 이름순으로 정렬하여 출력
		
		list.stream().sorted(new Comparator<Student>() {

			@Override
			public int compare(Student o1, Student o2) {
				// o2 => 내림차순
				return o1.getName().compareTo(o2.getName());
			}
			
		}).forEach(System.out::println);
		
	}

}

 

▣ Student

package day09;

public class Student {
	private String name;
	private int score;

public Student() {};

public Student(String name, int score) {
	this.name = name;
	this.score = score;
}

public String getName() {
	return name;
}

public void setName(String name) {
	this.name = name;
}

public int getScore() {
	return score;
}

public void setScore(int score) {
	this.score = score;
}

@Override
public String toString() {
	return name + " : " + score;
}



}

 

▷ 출력

출력 (5)

 

▣ StreamEx01

package day09;

import java.util.ArrayList;
import java.util.Comparator;

public class StreamEx01 {
	
	private String name;
	private int age;
	private int cost;
	
	public StreamEx01() {};
	
	public StreamEx01(String name, int age) {
		this.name = name;
		this.age = age;
	}
	
	public StreamEx01(String name, int age, int cost) {
		this.name = name;
		this.age = age;
		this.cost = cost;
	}

	public static void main(String[] args) {
		/* 과제
		 * 여행사 상품
		 * 여행 비용이 15세 이상은 100만원, 미만은 50만원으로 계산
		 * 고객 5명이 패키지 여행을 떠난다고 했을 경우
		 * 1. 비용계산 => 출력
		 * 2. 고객 명단 출력
		 * 고객 클래스로 생성하고, ArrayList로 고객관리
		 * 
		 * 예)
		 * 이름 : 이순신 나이 : 40 비용 : 100
		 * 이름 : 신사임당 나이 : 38 비용 : 100
		 * 이름 : 홍길동 나이 : 30 비용 100
		 * 이름 : 이짱구 나이 : 10 비용 : 50
		 * 이름 : 이짱아 나이 : 5 비용 : 50
		 * 총 여행 경비 : XXX
		 * 
		 * 20세 이상 고객명단 => 이름순으로 정렬
		 */
		
		ArrayList<StreamEx01> list = new ArrayList<>();

		list.add(new StreamEx01("신형만", 40));
		list.add(new StreamEx01("봉미선", 40));
		list.add(new StreamEx01("신짱구", 10));
		list.add(new StreamEx01("신짱아", 1));
		list.add(new StreamEx01("흰둥이", 1));
		
		list.stream().filter(n -> n.getAge() >= 15).forEach(m -> m.setCost(100));
		list.stream().filter(n -> n.getAge() < 15).forEach(m -> m.setCost(50));
		
		list.stream().forEach(n -> {
			String name = n.getName();
			int age = n.getAge();
			int cost = n.getCost();
			System.out.println("이름 : " + name + " | 나이 : " + age + " | 비용 : " + cost + "만원");
		});
		
		int sum = list.stream().mapToInt(n -> n.getCost()).sum();
		System.out.println("총 여행경비 : " + sum + "만원");
		
		System.out.println("--- 20세 이상 고객명단 ---");
		list.stream().filter(n -> n.getAge() >= 20).sorted(new Comparator<StreamEx01>() {

			@Override
			public int compare(StreamEx01 o1, StreamEx01 o2) {
				return o1.getName().compareTo(o2.getName());
			}
		}).forEach(n -> System.out.println("이름 : " + n.getName() + " | 나이 : " + n.getAge() + " | 비용 : " + n.getCost() + "만원"));
		
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getCost() {
		return cost;
	}

	public void setCost(int cost) {
		this.cost = cost;
	}

	@Override
	public String toString() {
		return "이름 : " + name + " | 나이 : " + age + " | 비용 : " + cost;
	}
	
}

 

※ 다른 풀이 과정

package day09;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class StreamEx01Teacher {

	public static void main(String[] args) {
		/* 여행사 상품
		 * 여행비용이 15세 이상은 100만원, 미만은 50만원으로 계산
		 * 
		 * 고객 5명이 패키지 여행을 떠난다고 했을 경우
		 * 1. 비용계산 => 출력
		 * 2. 고객 명단 출력
		 * 고객 클래스를 생성하고, ArrayList 로 고객관리
		 * 
		 * 예) 
		 * 이름:이순신 나이:40 비용: 100
		 * 이름:신사임당 나이:38 비용:100
		 * 이름:홍길동 나이:30 비용:100
		 * 이름:이짱구 나이:10 비용:50
		 * 이름:이짱아 나이:5 비용:50
		 * 총 여행경비 : xxx
		 * 
		 * 20세 이상 고객명단 => 이름순으로 정렬
		 * 이름:신사임당 나이:38 비용:100
		 * 이름:이순신 나이:40 비용: 100
		 * 이름:홍길동 나이:30 비용:100
		 * 
		 * */
		ArrayList<CustomerTeacher> list = new ArrayList<>();
		list.add(new CustomerTeacher("이순신", 40));
		list.add(new CustomerTeacher("신사임당", 38));
		list.add(new CustomerTeacher("홍길동", 30));
		list.add(new CustomerTeacher("이짱구", 10));
		list.add(new CustomerTeacher("이짱아", 5));
		
		int sum = 0;
		System.out.println("--고객명단--");
		for(CustomerTeacher tmp : list){
			String name = tmp.getName();
			int age= tmp.getAge();
			int price = tmp.getPrice();
			sum += price;
			System.out.println(name+"("+age+")"+" 비용:"+price+"만원");
		}
		System.out.println("-------------");
		System.out.println("총지불비용:"+sum+"만원");
		//Comparator 구현이 없는 경우
		list.sort(new Comparator<CustomerTeacher>() {

			@Override
			public int compare(CustomerTeacher o1, CustomerTeacher o2) {
				// TODO Auto-generated method stub
				return o1.getName().compareTo(o2.getName());
			}
		});
		
		Collections.sort(list); // 클래스에 정렬이 구현되어 있을경우 사용가능
		System.out.println("--20대 이상 명단--");
		for(CustomerTeacher tmp : list) {
			if(tmp.getAge() >= 20) {
				System.out.println(tmp);
			}
		}
		
		System.out.println("----Stream 이용방법----");
		
		list.stream().forEach(s->System.out.println(s));
		
		int total = list.stream()
				.mapToInt(n-> n.getPrice())
				.sum();
		System.out.println("---총지불금액:"+total);
		
		//20세이상
		System.out.println("--20세 이상--");
		list.stream()
		.filter(s->s.getAge()>=20)
		.sorted()// 기존 클래스에서 구현
		.forEach(a->System.out.println(a));
		
		//익명클래스 사용할 경우 Comparator 대상값이 (매개변수가) 2개
		//클래스 내부에서 구현할 경우 Comparable 대상값이 (매개변수) 1개
	}

}

 

package day09;

public class CustomerTeacher implements Comparable<CustomerTeacher> {

	//멤버변수 : 각 인원마다 가져야 할 고유 값
	private String name;
	private int age;
	private int price;
	
	//생성자
	public CustomerTeacher(String name, int age) {
		this.name = name;
		this.age = age;
		this.price = (age>=15)? 100 : 50;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return name+"("+age+")"+" 비용:"+price+"만원";
	}

	@Override
	public int compareTo(CustomerTeacher o) {
		// this 와 o 객체를 정렬
		return this.name.compareTo(o.name);
	}
}

 

▷ 출력

출력 (6)