17. Path p = Paths.get(“/home”, “nabi”, “my”);
Path p = p.getParent(); /home/nabi
Path p = p.getFileName(); /my
Path p = p.getRoot(); / (상대경로의 경우 null)
Byte[] bytes = Files.readAllBytes(path); 파일의 내용을 읽기
String content = new String(bytes, StandardCharsets.UTF_8); 문자열로 읽기
List<String> lines = Files.readAllLines(path); 행으로 읽기
Files.write(path, content.getBytes(StandardCharsets.UTF_8)); 문자열 쓰기
Files.write(path, lines); 행들로 구성된 컬렉션 쓰기
Files.write(path, lines, StandardOpenOption.APPEND); 파일에 내용 추가
경로
파일 읽고 쓰기
Files.createDirectory(path);
Files.createDirectories(path); 중간 디렉토리까지 모두 생성
Files.createFile(path); 빈 파일 생성
파일과 디렉토리 생성
Files.copy(fromPath, toPath); 복사
Files.move(fromPath, toPath); 이동
Files.copy(fromPath, toPath, StandardCopyOption.REPLACE_EXISTING); 덮어쓰기
Files.move(fromPath, toPath, StandardCopyOption.ATOMIC_MOVE); 원자성 보장
Files.delete(path); 삭제
파일 제어
18. private void init() {
path = Paths.get("D:");
try {
watchService = FileSystems.getDefault().newWatchService(); WatchKey를 가지고 있는 큐로 구성
path.register(watchService, ENTRY_CREATE, ENTRY_DELETE, ..); 모니터링 대상과 이벤트 타입 등록
…
}
private void watch() {
WatchKey key= null;
while(true) {
try {
key = watchService.take(); 이벤트 잡기 시작
for (WatchEvent<?> event : key.pollEvents()) {
WatchEvent.Kind<?> kind = event.kind();
System.out.println("Event on " + event.context().toString() + " is " + kind);
}
…
boolean reset = key.reset();
if ( ! reset) break;
}
NIO 2.0의 File Change Notifications
19. InheritIO Method
ProcessBuilder bd = new ProcessBuilder(“ls”, “-al”);
Bd.redirectOutput(Paths.get(“iden.txt”).toFile());
Process process = builder.start();
Boolean complete = process.waitFor(1, TimeUnit.MINUTES); 이건 사실 8의 기능..
ProcessBuilder bd = new ProcessBuilder(“ls”, “-al”);
bd.inheritIO();
bd.start().waitFor();
inheritIO 메서드는
프로세스의 표준 입/출력, 오류 스트림을
자바의 표준 입/출력, 오류 스트림으로 변경
20. 그 외 몇 가지..
Map<String, List<String>> map = new HashMap<String, List<String>>();
<> 지시자
Map<String, List<String>> map = new HashMap<>(); 간결하게..
Objects.equals(a, b); 둘다 null이면 true, a만 null이면 false, 그 외에는 a.equals(b)를 리턴
Objects.equals로 null 안전 동등성 테스트를 ..
Arrays.hashCode를 이용할 수도 있지만 Arrays.hashCode는 가변 인자 Method가 아니라 불편했었다.
Objects.hash 메서드
Objects.hash(first, last); 이 Method는 지정값들의 Hash code를 결합한다.
정말 그 외..
Switch문의 String 지원
문자열 숫자 변환 문제 해결
Binary integer literals
등등..
int million = 1_000_000;
Allowing underscores in numeric literals
22. JAVA SE 8
• 람다
• 스트림 API
• JavaFX
• 나스혼 JS 엔진
• 그 외..
23. (인자목록) -> { 구문 }
(final String f, @NonNull String s) -> // 메서드 파라미터와 같은 형식
Integer.compare(f.length(), s.length())
(String f, String s) -> { // 메서드가 길어질 경우 괄호 사용
if (f.length() < s.length()) return -1;
else if (f.length() > s.length()) return 1;
else return 0; // 결과 타입은 문맥에서 추정
}
// 파라미터의 타입이 추정가능할 경우 타입 생략 가능
Comparator<String> comp = (f, s)
-> Integer.compare(f.length(), s.length());
( ) -> { System.out.println(“Hello World!”);
24. 모든 람다의 핵심은 지연 실행(deferred execution)
예 )
• 별도의 스레드에서 코드 실행
• 코드를 여러 번 실행
• 알고리즘에서 코드를 적절한 시점에 실행
• 어떤 일이 발생했을 때 코드 실행
• 필요할 때만 코드 실행
25. 짧게 요약하면 !
람다 표현식을 이용하는 주 이유는 적절한 시점까지
코드의 실행을 지연시키기 위해 작성한
전달 가능한 코드 블록
26. class Worker implements Runnable {
public void run() {
for (int i = 0; i < 100; i++) {
doWork();
}
}
}
Worker w = new Worker();
New Thread(w).start();
class LenthComparator implements Comparator<String> {
public int compare(String f, String s) {
return Integer.compare(f.length(), s.length());
}
}
Array.sort(Strings, new LengthComparator());
Button.setOnAction(new EventHandler<ActionEvent>() {
public void handle(ActionEvent event) {
System.out.println(“OK!”);
}
}
코드 블록을 어딘가로 전달하고 얼마 후에 호출된다.
32. public static void repeatMessage(String test, int count) {
Runnable r = () -> {
for (int i = 0; i < count; i++) {
System.out.println(text);
Thread.yield();
}
};
new Thread(r).start();
}
…
repeatMessage(“Hello”, 1000)
• count와 text는 람다에 정의되어 있지 않다.
• 람다는 지연 실행을 위해 존재한다.
33. 람다를 구성하고 있는 것은 하나 더 있다.
1. 코드 블록
2. 파라미터
3. 자유변수
35. JAVA SE 8
• 람다
• 스트림 API
• JavaFX
• 나스혼 JS 엔진
• 그 외..
36. List<String> words = Arrays.asList(contents.split(“[P{L}]+”));
int count = 0;
for (String w : words) {
if (w.length() > 10) count++;
}
long count = words.stream().filter(w -> w.length() > 12).count();
일반 순회 처리 코드를 스트림 API로 ..
38. words.stream().filter(w -> w.length() > 12).count();
스트림 연산 파이프라인
스트림생성 중간 연산 최종 연산
• stream
• parallelStream
• filter
• map
• distinct
• flatMap
• sorted
• peek
• limit
• skip
• toArray
• foreach
• collect
• reduce
• min
• max
• count
• firstFind
• anyFind
• anyMatch
• allMatch
• nonMatch
최종연산 이후에는 해당 스트림을 더 이상 사용할 수 없다.
39. JAVA SE 8
• 람다
• 스트림 API
• JavaFX
• 나스혼 JS 엔진
• 그 외..
40. JAVA의 구린 GUI 역사
AWT
• 크로스플랫폼
• 각 운영체제의 네이티브 GUI 요소 프로그래밍 인터페이스 제공
• 생각만큼 잘 동작하지 않았고 각 운영체제마다 미묘한 차이를 가짐
스윙
• 네이티브를 사용하지 않고 자체적으로 드로잉하는 방식
• 모든 플랫폼에서 동일한 효과
• 덕분에 좋지 않은 성능
JavaFX (2.2 까지)
• 플래시의 경쟁자라 자칭
• JVM위에서 돌아가지만 자체적인 스크립트 언어로 인해 거부감을 줌
41. 그리고 JavaFX 8
• 람다와 결합된 비교적 간단한 사용
• 선언형 언어를 이용한 레이아웃 지정 (HTML, CSS, FXML)
• ARM 플랫폼 지원
• 스윙 컴포넌트와 친화력 강화
• 3D Graphics API 추가
• Canvas API
• Multi-touch 지원
• Hi-DPI 디스플레이 지원
42. JAVA SE 8
• 람다
• 스트림 API
• JavaFX
• 나스혼 JS 엔진
• 그 외..
44. 새로운 인터프리터 나스혼 (Nashorn)
• 새로운 JVM 인스트럭션을 사용하여 효율적인 성능을 냄
• ECMAScript 표준을 잘 준수
• jjs 인터프리터와 자바 스크립팅 API를 제공
• 자바빈즈 프로퍼티, 리스트와 맵을 다루는 편리한 문법 제공
• 람다 표현식 사용과 유사한 방식으로 자바스크립트 함수를
자바 인터페이스로 변환 가능
45. ScriptEngineManager manager = new ScriptEnginManager();
ScriptEngine engine = manager.getEnginByName(“nashorn”);
Object result = engine.eval(“’Hello, World!’.length”);
System.out.println(result);
나스혼 실행
JAVA8과 함께 제공되는 jjs 명령행 도구 이용
JAVA6부터 제공한 스크립트 엔진 메커니즘 사용
46. 나스혼과 JavaFX
var message = new javafx.scene.control.Label("Hello, JavaFX!");
message.font = new javafx.scene.text.Font(100);
$STAGE.scene = new javafx.scene.Scene(message);
$STAGE.title = "Nashorn!";
47. 그 외 몇 가지..
• Join 메서드 (Java8에 String 클래스에 추가된 유일한 메서드)
• Base64 표준 인코더/디코더 제공
• Annotation 개선
• 날짜/시간 API 개선
• JDBC 4.2 업데이트