T.김동식
맵 리듀스 MapReduce
*Reduce 축약하다
*하둡, 빅데이터 솔루션
구글에서 대용량 데이터처리를 목적으로 발표한 소프트웨어 프레임 워크
자바로 이루어짐.
예) A, A, B, C -> A 2, B 1, C 1
stream().reduce()
스트림의 원소들을 하나씩 소모해가며, 누적 계산을 수행하고 결과값을 리턴하는 메서드
* Arrays.stream().reduce(초기값, 함수λ(a, b)->a+b )
ArrayList arr = new ArrayList();
arr.add("A");
arr.add("B");
arr.add("C");
arr.stream().reduce("0", (a, b) -> a+", "+b);
System.out.println(arr.toString());
System.out.println(arr.stream().reduce("0", (a, b) -> a+", "+b));
//[A, B, C]
//0, A, B, C
이클립스
ctrl shift o import 단축키
getBytes().length
배열 길이 구하기
String st1 = "hello";
String st2 = "안녕";
byte[] bytes1 = st1.getBytes();
byte[] bytes2 = st2.getBytes();
System.out.println(bytes1.length); //5
System.out.println(bytes2.length); //6
함수형 인터페이스
자바에서 제공
람다식(Lambda)을 사용하기 위해서(자바의 람다식은 함수형 인터페이스로만 접근)
매번 함수형 인터페이스를 매번 각각의 인터페이스/함수의 타입/이름 등을 직접 정의/생성하는 불편함을 해결
예)
Function<T, R>
BiFunction<T, U, R>
Consumer<T>
Supplier<T>
Predicate<T>
UnaryOperator<T>
BinaryOperator<T>
BinaryOperator<T>
BiFunction<T, U, R>의 특수한 형태로,
동일한 타입의 입력값 두 개를 받아 리턴하는 함수 인터페이스
1. BinaryOperator import + lambda
BinaryOperator<Integer> add = (i, j) -> i + j;
System.out.println(add.apply(10, 20));//40
2. class에 implements BinaryOperator하여 구현
import java.util.function.BinaryOperator;
public class BinaryTest implements BinaryOperator<Integer>{
@Override
public Integer apply(Integer i, Integer j) {return i + j;}
}
BinaryTest binaryTest = new BinaryTest();
System.out.println(binaryTest.apply(10, 20));
Stream
바이트스트림(객체)
- 입력: inputStream
- 출력: putStream
문자스트림(메모장을 상상하라)
- 입력: Reader
- 출력: Writer
stream 출력
TravelCustomer person1 = new TravelCustomer("박상희1", 10, 100);
TravelCustomer person4 = new TravelCustomer("박상희4", 40, 400);
TravelCustomer person2 = new TravelCustomer("박상희2", 20, 200);
TravelCustomer person3 = new TravelCustomer("박상희3", 30, 300);
List<TravelCustomer> travelCustomers = new ArrayList<TravelCustomer>();
travelCustomers.add(person1);
travelCustomers.add(person4);
travelCustomers.add(person2);
travelCustomers.add(person3);
//forEach()
travelCustomers.stream().map(t -> t.getName()).forEach(s->System.out.print(s + " ")); //박상희1 박상희4 박상희2 박상희3
travelCustomers.stream().mapToInt(t->t.getPrice()).forEach(s->System.out.print(s + " ")); //100 400 200 300
//sum/average
System.out.println(travelCustomers.stream().mapToInt(t->t.getPrice()).sum()); //1000
System.out.println(travelCustomers.stream().mapToDouble(t->t.getPrice()).average().getAsDouble()); //250.0
//filter()
travelCustomers.stream().filter(t -> t.getAge() >=20).map(t -> t.getName()).forEach(s -> System.out.print(s+ " ")); //박상희4 박상희2 박상희3
travelCustomers.stream().filter(t -> t.getAge() >=20).map(t -> t.getName()).sorted().forEach(s -> System.out.print(s+ " ")); //박상희2 박상희3 박상희4
예외처리 throws
이클립스에서 에러가 난 사유를 보고 ctrl c + ctrl v
*FileInputStream 파일을 읽어올때 사용
*Class.forName 클래스의 정보를 얻어오는 클래스
public Class loadClass(String fileName, String className)
throws FileNotFoundException, ClassNotFoundException {
FileInputStream fis = new FileInputStream(fileName); // FileNotFoundException
Class cl = Class.forName(className); // ClassNotFoundException
return cl;
}
예외처리 try+Catch
String url_true1 = "C:\\Users\\409\\eclipse-workspace\\advanced\\src\\Chapter14\\a.txt";
String url_true2 = "src/Chapter14/a.txt";
String url_false = "a.txt";
try {
FileInputStream fis = new FileInputStream(url_true2);
System.out.println("- 파일을 발견했습니다.");
fis.close();
} catch (Exception e) {
System.out.println("- 파일이 존재하지 않습니다.");
}finally {
System.out.println("- 파일확인을 완료했습니다.");
}
[출력결과]
파일확인
- 파일을 발견했습니다.
- 파일확인을 완료했습니다.
AutoCloseable
*close() 자원의반납
리소스(입출력/하드웨어)는 모든 작업에서 요청시 공유되어
사용되기에 열었으면 닫아야한다라는 개념이 있다.
//AutoCloseable
public class AutoCloseObj implements AutoCloseable {
@Override
public void close() throws Exception {System.out.println("리소스가 닫혔습니다.");}
}
public static void main(String[] args) {
//1번째 방법
try (AutoCloseObj obj = new AutoCloseObj()) {}
catch (Exception e) {}
//2번째 방법 - 권장
AutoCloseObj obj = new AutoCloseObj();
try (obj) {}
catch (Exception e) {}
}
throw new Exception()
강제로 예외를 발생시킴
문법적으로 오류가 있는것이 아닌 실제로 실행해봐야 알 수 있는 경우가 있다.
오류 테스트시 이용
오류형식 만들기
//extends Exception
public class IDFormatException extends Exception{
public IDFormatException(String message) {super(message);}
}
//throws Class명 + throw new Class명
public class IDFormatTest {
private String userID;
public String getUserID() {return userID;}
public void setUserID(String userID) throws IDFormatException {
if (userID == null) {
throw new IDFormatException("ID값이 없습니다.");
} else if (userID.length() < 8 || userID.length() > 20) {
throw new IDFormatException("ID는 8자이상, 20자 이하로 쓰세요.");
}
this.userID = userID;
}
//테스트
public static void main(String[] args) {
IDFormatTest test = new IDFormatTest();
String userID = null;
String userID = "shafkuljsalkgltdskfgblsjldf";
String userID = "shafkuddd";
try {
test.setUserID(userID);
System.out.println("사용가능한 ID입니다.");
} catch (IDFormatException e) {
e.printStackTrace();}
}
Servlet
request url에서 요청
seeetion 접속을 유지하는 범위
sendRedirect+getParameter
전달하는 데이터의 양이 적을때는 get방식이 편리하다.
https://sanghee.tistory.com/89/#redirect_sanghee
response.sendRedirect("sanghee2?a=b");
PrintWriter pw = response.getWriter();
String a = request.getParameter("a");
pw.print(a);
dispatch + 바인딩
(setAttribute+RequestDispatcher+forward)+(getAttribute)
데이터베이스에서 조회된 수십개의 회원정보나 상품정보를 전달해야한다면 get 방식이 불편하다.
바인딩관련 메서드
setAttribute: 데이터를 각객체에 바인딩
getAttribute: 바인딩한 자원을 name으로 가져옴
removeAttribute: 바인딩한 자원을 name으로 제거함
request.setAttribute("a", "b");
RequestDispatcher dispatch = request.getRequestDispatcher("sanghee2");
dispatch.forward(request, response);
PrintWriter pw = response.getWriter();
String a = (String)request.getAttribute("a");
pw.print(a);
ServletContext
인터페이스, 웹서버에 등록된 웹 애플리케이션 단위로 하나의 ServletContext 객체가 자동으로 생성
웹 애플리케이션 서비스가 중지될 때 소멸
메소드를 이용해 ServletContext 객체를 추출할 수 있다.
* 실제로는 setAttribute와 getAttribute를 많이 이용한다.
아래는 교재에 있는 리스트를 한번 테스트한 결과, 필요할때 서치/찾아서 쓰는 개념으로 중요하지않다.
@WebServlet(urlPatterns = "/cset",
initParams = {@WebInitParam(name = "initParams", value = "initParamsValue")},
loadOnStartup = 1
)
//urlPatterns = {"/name1", "/name2", "/name3"} 형식으로 이용.
//initParams = 초기 파라미터, key value 객체를 만들 수 있다.
//loadOnStartup = 톰캣이 실행됨과 동시에 서블릿을 수행해 보다 빠른결과확인 가능, 0보다 큰숫자로, 작은숫자순서대로 수행
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//ServletContext가 제공
ServletContext context = getServletContext();
//... 이 부분에 작성해 테스트 했다.
}
System.out.println("초기화 파라미터값 가져오기");
//initParams 초기화 파라미터
System.out.println("getInitParameter: "+getInitParameter("initParams"));
//초기화 파라미터값 가져오기
//getInitParameter: initParamsValue
System.out.println();
System.out.println("xml에 작성한 파라미터값 가져오기");
Enumeration getInitParameterNames = context.getInitParameterNames();
while(getInitParameterNames.hasMoreElements()) {
String name = (String) getInitParameterNames.nextElement();
System.out.println("getInitParameterNames: "+name);
}
//xml에 작성한 파라미터값 가져오기
//getInitParameterNames: 파라미터이름
System.out.println();
System.out.println("프로젝트 정보가져오기");
//getContext
System.out.println("현제경로 객체: "+context.getContextPath());
//프로젝트 이름
System.out.println("이름: "+context.getServletContextName());
//getRealPath 해당프로젝트의 절대경로
System.out.println("절대경로: "+context.getRealPath(getServletInfo()));
//getResource 해당프로젝트의 resource
System.out.println("resource: "+context.getResource(getServletInfo()));
//프로젝트 정보가져오기
//현제경로 객체: /pro08_1
//이름: pro08_1
//절대경로: C:\Users\409\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp3\wtpwebapps\pro08_1\
//resource: file:/C:/Users/409/eclipse-workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp3/wtpwebapps/pro08_1/
System.out.println();
System.out.println("서블릿 정보가져오기");
//getMajorVersion 서블릿이 지원하는 주요 서블릿 api버전
System.out.println("api버전: Version"+context.getMajorVersion());
//getServerInfo 서블릿이 실행되고 있는 서블릿이름과 버전(톰캣정보)
System.out.println("실행정보: "+context.getServerInfo());
// 서블릿 정보가져오기
// api버전: Version4
// 실행정보: Apache Tomcat/9.0.70
//removeAttribute
System.out.println();
System.out.println("객체 제거하기");
context.setAttribute("deleteKey", "deleteValue");
System.out.println(context.getAttribute("deleteKey")+"를 삭제를 해볼겁니다");
context.removeAttribute("deleteKey");
System.out.println("deleteKey 삭제함");
System.out.println("삭제확인: "+context.getAttribute("deleteKey"));
//객체 제거하기
//deleteValue를 삭제를 해볼겁니다
//deleteKey 삭제함
//삭제확인: null
//@WebServlet("/cget") 에서 테스트하기위한 세팅
//setAttribute + getAttribute
context.setAttribute("keyA", "valueA");
//setAttribute + getAttribute List 응용
List sanghee = new ArrayList();
sanghee.add("박상희1");
sanghee.add("박상희2");
context.setAttribute("keyB", sanghee);
아래부터는
@WebServlet("/cget") 에서 테스트했다.
//setAttribute + getAttribute
System.out.println();
System.out.println("객체 값 가져오기");
String str = (String)context.getAttribute("keyA");
System.out.println("setAttribute + getAttribute: "+str);
// 객체 값 가져오기
// setAttribute + getAttribute: valueA
//setAttribute + getAttribute List 응용
System.out.println();
System.out.println("객체 리스트에 넣어 가져오기");
List list = (List)context.getAttribute("keyB");
System.out.print("setAttribute + getAttribute List 응용 :"+list.get(0)+", ");
System.out.println(list.get(1));
// 객체 리스트에 넣어 가져오기
// setAttribute + getAttribute List 응용 :박상희1, 박상희2
저장된 모든 정보 가져오기
System.out.println("저장된 모든 정보 가져오기");
Enumeration enumeration1 = context.getAttributeNames();
System.out.println("----------------------------------------");
while(enumeration1.hasMoreElements()) {
System.out.println(context.getAttributeNames());
String key = enumeration1.nextElement().toString();
String value = (String) context.getAttribute(key).toString();
System.out.println(key+":"+value);
}
System.out.println("----------------------------------------");
// 저장된 모든 정보 가져오기
// ----------------------------------------
// java.util.Collections$3@63ae21ba
// javax.servlet.context.tempdir:C:\Users\409\eclipse-workspace\.metadata\.plugins\org.eclipse.wst.server.core\tmp3\work\Catalina\localhost\pro08_1
// java.util.Collections$3@6d69c3bf
// keyA:valueA
// java.util.Collections$3@69564aca
// keyB:[박상희1, 박상희2]
// java.util.Collections$3@2c54c984
// org.apache.catalina.resources:org.apache.catalina.webresources.StandardRoot@396394ef
// java.util.Collections$3@3e659e45
// org.apache.catalina.webappVersion:
// java.util.Collections$3@1d32c60d
// org.apache.tomcat.InstanceManager:org.apache.catalina.core.DefaultInstanceManager@46e9cf7b
// java.util.Collections$3@4c7b36cb
// org.apache.catalina.jsp_classpath:/C:/tomcat9/lib/;/C:/tomcat9/lib/annotations-api.jar;/C:/tomcat9/lib/catalina-ant.jar;/C:/tomcat9/lib/catalina-ha.jar;/C:/tomcat9/lib/catalina-ssi.jar;/C:/tomcat9/lib/catalina-storeconfig.jar;/C:/tomcat9/lib/catalina-tribes.jar;/C:/tomcat9/lib/catalina.jar;/C:/tomcat9/lib/ecj-4.20.jar;/C:/tomcat9/lib/el-api.jar;/C:/tomcat9/lib/jasper-el.jar;/C:/tomcat9/lib/jasper.jar;/C:/tomcat9/lib/jaspic-api.jar;/C:/tomcat9/lib/jsp-api.jar;/C:/tomcat9/lib/servlet-api.jar;/C:/tomcat9/lib/tomcat-api.jar;/C:/tomcat9/lib/tomcat-coyote.jar;/C:/tomcat9/lib/tomcat-dbcp.jar;/C:/tomcat9/lib/tomcat-i18n-cs.jar;/C:/tomcat9/lib/tomcat-i18n-de.jar;/C:/tomcat9/lib/tomcat-i18n-es.jar;/C:/tomcat9/lib/tomcat-i18n-fr.jar;/C:/tomcat9/lib/tomcat-i18n-ja.jar;/C:/tomcat9/lib/tomcat-i18n-ko.jar;/C:/tomcat9/lib/tomcat-i18n-pt-BR.jar;/C:/tomcat9/lib/tomcat-i18n-ru.jar;/C:/tomcat9/lib/tomcat-i18n-zh-CN.jar;/C:/tomcat9/lib/tomcat-jdbc.jar;/C:/tomcat9/lib/tomcat-jni.jar;/C:/tomcat9/lib/tomcat-util-scan.jar;/C:/tomcat9/lib/tomcat-util.jar;/C:/tomcat9/lib/tomcat-websocket.jar;/C:/tomcat9/lib/websocket-api.jar;C:\tomcat9\bin\bootstrap.jar;C:\tomcat9\bin\tomcat-juli.jar
// java.util.Collections$3@5e7e0eb7
// javax.websocket.server.ServerContainer:org.apache.tomcat.websocket.server.WsServerContainer@5577a9db
// java.util.Collections$3@5ded2619
// org.apache.jasper.compiler.TldCache:org.apache.jasper.compiler.TldCache@48358e01
// java.util.Collections$3@66903a06
// org.apache.tomcat.JarScanner:org.apache.tomcat.util.scan.StandardJarScanner@25478477
// ----------------------------------------
전체 console.log 기록