Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Java: The Past and Present
Search
TATSUNO Yasuhiro
November 30, 2014
Programming
3
790
Java: The Past and Present
2014年11月30日, なごやかJava 第1回: Java 1.0 から Java 8 への20年をふりかえる
TATSUNO Yasuhiro
November 30, 2014
Tweet
Share
More Decks by TATSUNO Yasuhiro
See All by TATSUNO Yasuhiro
Bun に LCOV 出力を実装した
exoego
2
82
terraform-provider-aws にプルリクして マージされるまで
exoego
2
330
ライブラリをパブリッシュせずにすばやく試す
exoego
2
200
esbuild 最適化芸人
exoego
3
1.6k
いい感じに AWS を組み合わせたビルディングブロックでアプリ開発を支援する / TdTechTalk 2022 11
exoego
0
580
Empowering App Dev by Nicely-Crafted High-Level AWS Components
exoego
0
33
月間数十億リクエストのマイクロサービスを支える JVM+AWS フルサーバーレス開発事例 / Now and Future of Fully Serverless development at Chatwork
exoego
1
670
Scala と AWS でフルサーバーレス開発事例 / How Chatworks uses Scala and Serverless
exoego
3
1.4k
忙しい Scala 開発者の超時間節約術 / Big Timesavers for Busy Scala Developers
exoego
1
1.1k
Other Decks in Programming
See All in Programming
初めてDefinitelyTypedにPRを出した話
syumai
0
410
Remix on Hono on Cloudflare Workers
yusukebe
1
290
色々なIaCツールを実際に触って比較してみる
iriikeita
0
330
[Do iOS '24] Ship your app on a Friday...and enjoy your weekend!
polpielladev
0
100
Arm移行タイムアタック
qnighy
0
320
ActiveSupport::Notifications supporting instrumentation of Rails apps with OpenTelemetry
ymtdzzz
1
230
AI時代におけるSRE、 あるいはエンジニアの生存戦略
pyama86
6
1.1k
リアーキテクチャxDDD 1年間の取り組みと進化
hsawaji
1
220
最新TCAキャッチアップ
0si43
0
140
Laravel や Symfony で手っ取り早く OpenAPI のドキュメントを作成する
azuki
2
120
subpath importsで始めるモック生活
10tera
0
300
C++でシェーダを書く
fadis
6
4.1k
Featured
See All Featured
The Invisible Side of Design
smashingmag
298
50k
How STYLIGHT went responsive
nonsquared
95
5.2k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.1k
How to train your dragon (web standard)
notwaldorf
88
5.7k
GraphQLとの向き合い方2022年版
quramy
43
13k
Music & Morning Musume
bryan
46
6.2k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
PRO
10
720
Automating Front-end Workflow
addyosmani
1366
200k
Dealing with People You Can't Stand - Big Design 2015
cassininazir
364
24k
4 Signs Your Business is Dying
shpigford
180
21k
Transcript
None
None
None
None
None
None
None
None
None
None
None
• • • •
None
• • • • • •
• • • • • •
None
None
None
None
None
1 2 3 4 5 • • • • •
• • • •
• • • • • •
None
final Class a = List.class; final Class b = String.class;
final Class c = double.class; final Class d = int[][].class; • •
import java.awt.Event; public class MyApp extends java.applet.Applet { public boolean
action(Event evt, Object arg) { if (evt.target == APPROVE_BUTTON) { return doSomething1(evt, arg); } else if (evt.target == REJECT_BUTTON) { return doSomething2(evt, arg); } else if (evt.target == DATE_CHOICE) { return doSomething3(evt, arg); } … return super.action(evt, arg); } import java.awt.event.*; public class MyApp2 extends java.applet.Applet { public void init() { this.addMouseListener(new MyMouseAdapter()); Button approveButton = new Button("承認"); approveButton.addActionListener(new ApproveListner()); this.add(approveButton); } }
import java.awt.event.*; public class MyApp2 extends java.applet.Applet { public void
init() { this.addMouseListener(new MyMouseAdapter()); Button approveButton = new Button("承認"); approveButton.addActionListener(new ApproveListner()); this.add(approveButton); } } import java.awt.event.*; public class ApproceListner implements ActionListener { public void actionPerformed(final ActionEvent e) { // 承認 // 承認 // 承認 } }
import java.awt.event.*; public class MyApp3 extends java.applet.Applet { public class
ApproceListner implements ActionListener { public void actionPerformed(final ActionEvent e) { // 承認 // 承認 // 承認 } } public void init() { this.addMouseListener(new MyMouseAdapter()); Button approveButton = new Button("承認"); approveButton.addActionListener(new ApproveListner()); this.add(approveButton); } } • • •
import java.awt.event.*; public class MyApp3 extends java.applet.Applet { public class
ApproceListner implements ActionListener { public void actionPerformed(final ActionEvent e) { // 承認 // 承認 // 承認 } } public void init() { this.addMouseListener(new MyMouseAdapter()); Button approveButton = new Button("承認"); approveButton.addActionListener(new ApproveListner()); this.add(approveButton); } }
import java.awt.event.*; public class MyApp4 extends java.applet.Applet { public void
init() { this.addMouseListener(new MyMouseAdapter()); Button approveButton = new Button("承認"); approveButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { // 承認 // 承認 // 承認 } }); this.add(approveButton); } } • • •
import java.awt.event.*; public class MyApp4 extends java.applet.Applet { public void
init() { this.addMouseListener(new MyMouseAdapter()); Button approveButton = new Button("承認"); approveButton.addActionListener(new ActionListener() { public void actionPerformed(final ActionEvent e) { // 承認 // 承認 // 承認 } }); this.add(approveButton); } }
import java.awt.event.*; public class MyApp4 extends java.applet.Applet { public void
init() { this.addMouseListener(new MyMouseAdapter()); Button approveButton = new Button("承認"); approveButton.addActionListener({ // 承認 // 承認 // 承認 }); this.add(approveButton); } } 結果 = sort(users, 名前でソート); 結果 = sort(users, 年齢でソート); 結果 = sort(users, 所属部署でソート); 結果 = filter(users, 名古屋に住んでいる); 結果 = filter(users, 関数型言語が好きである); 結果 = filter(users, リア充である); 結果 = transform(users, 名前を大文字に); 結果 = transform(users, 給与を半分に);
• • • •
None
None
None
None
None
None
1 2 3 4 5 • • • • •
• • • • • • • • • • •
• • •
None
None
None
None
None
1 2 3 4 5 • • • • •
• • • •
• • •
• • •
List list = (List) Proxy.newProxyInstance(List.class.getClassLoader(), new Class[]{ List.class }, new
MyInvocationHandler());
None
None
None
1 2 3 4 5 • • • • •
• • • • • • • • • • • • • • • • • • • • •
• • • • •
• • try { doSomething(); } catch (LowLevelException cause) {
throw new HighLevelException( "••が▲▲です", cause); }
• • • • • • • • • •
• • • • • • •
• • • • • •
• •
None
• • • • • •
• • • • Charset sjis = Charset.forName("Shift-JIS"); InputStream is
= new FileInputStream(new File("hoge.txt")); Reader reader = new BufferedReader(new InputStreamReader(is, sjis));
• • • • • • • •
None
None
1 2 3 4 5 • • • • •
• • • • • • • • • • • • • • • • • • • • • • • • • • • •
List names = ……; names.add(9999); for (int i = 0;
i < names.size(); i++) { String name = (String) names.get(i); System.out.println(name); }
None
• • List names = ……; for (int i =
0; i < names.size(); i++) { // まじこわいキャスト String name = (String) names.get(i); System.out.println(name); } // 中身なんて知ったことか!! names.add(9999); List<String> names = ……; for (int i = 0; i < names.size(); i++) { String name = names.get(i); System.out.println(name); } names.add(9999);
None
None
• • • • •
int pri = 1; Integer b = Integer.valueOf(pri); int pri
= 1; Integer b = pri;
@Test(expected = NoSuchElementException.class) @Ignore public void getShouldFailIfEmtpy() { Optional.empty().get(); }
None
public enum Imoni { YAMAGATA, FUKUSHIMA, MIYAGI, MIX; } public
enum Suite { SPADE, HEART, CLUB, DIAMOND; } public enum Janken { ROCK, PAPER, SCISSOR; } public enum JapaneseProvince { TOKYO, HOKKAIDO, … AICHI, … OKINAWA } assert Suite.SPADE != Suite.HEART; assert Suite.SPADE != Janken.ROCK;
• • • public enum Planet { MERCURY(3.303e+23, 2.4397e6), VENUS(4.869e+24,
6.0518e6), EARTH(5.976e+24, 6.37814e6), MARS(6.421e+23, 3.3972e6), JUPITER(1.9e+27, 7.1492e7), SATURN(5.688e+26, 6.0268e7), URANUS(8.686e+25, 2.5559e7), NEPTUNE(1.024e+26, 2.4746e7); private final double mass; private final double radius; Planet(double mass, double radius) { this.mass = massKillogram; this.radius = radiusMeter; } public static final double G = 6.67300E-11; public double surfaceGravity() { return G * mass / (radius * radius); }
Set<Planet> 全部 = EnumSet.allOf(Planet.class); Set<Planet> 地球以外 = EnumSet.complementOf(EnumSet.of(EARTH)); Map<Imoni, Integer>
芋煮種人気 = new EnumMap<Imoni, Integer>(Imoni.class); 芋煮種人気.put(Imoni.FUKUSHIMA, 1024); 芋煮種人気.put(Imoni.YAMAGATA, 256); 芋煮種人気.put(Imoni.MIX, -9999);
List<String> src = Arrays.asList("Java", "Scala", "Clojure"); Set<String> langs = new
HashSet<>(src); Iterator<String> iterator = langs.iterator(); while (iterator.hasNext()) { String e = iterator.next(); System.out.println(e); } Iterator<String> iterator2 = langs.iterator(); for (String e; iterator2.hasNext(); ) { e = iterator2.next(); System.out.println(e); } String[] array = {"Ruby", "Python", "JavaScript"}; for (int i = 0; i < array.length; i++) { String e = array[i]; System.out.println(e); } for (final String e : langs) { System.out.println(e); } for (final String e : array) { System.out.println(e); }
None
Maybe<String> maybeName = …; Maybe<Integer> maybeAge = …; for (String
name : maybeName) { for (int age : maybeAge) { return String.format("%sさんは%s歳です", name, age); } } return "そんな人はいないか、年齢が分かりません!!";
public static int sum(int... ints) { int sum = 0;
for (int i : ints) { sum += i; } return sum; } public static void main(String... args) { System.out.println(sum(1)); System.out.println(sum(2, 3, 4)); System.out.println(sum(new int[]{5, 6})); }
import static java.lang.Math.random; import static java.lang.Math.floor; public class NewStyle {
public static void main(String[] args) { double x = floor(random() * 100); System.out.println(x); } } public class FormerStyle { public static void main(String[] args) { double d = Math.floor(Math.random() * 100); System.out.println(d); } }
List<String> mutableList = newArrayList("Java", "Scala", "Clojure"); Set<String> mutableSet = newHashSet("Java",
"Scala", "Clojure");
None
None
None
None
1 2 3 4 5 • • • • •
• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •
• • •
// 先頭からn件 final String[] original = {"Java", "Scala", "F#", "C#",
"Haskell", "Python"}; final String[] first3 = Arrays.copyOf(original, 3); assertThat(first3, is(new String[]{"Java", "Scala", "F#"})); // i番目~j-1番目まで final int[] original2 = {0, 10, 20, 30, 40, 50}; final int[] range = Arrays.copyOfRange(original2, 3, 5); assertThat(range, is(new int[]{30, 40}));
None
• • • • • •
@Override @SuppressWarnings("unchecked") public void actionPerformed(final ActionEvent e) { return (Class<T>)
foo.getClass(); }
• •
None
None
None
None
None
None
None
None
1 2 3 4 5 • • • • •
• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •
• • • • • • •
ZipFile zf = new ZipFile(zipFileName); try { BufferedWriter writer =
Files.newBufferedWriter(outputPath, charset); try { for (ZipEntry entry : Collections.list(zf.entries())) { String entryName = entry.getName() + newLine; writer.write(entryName, 0, entryName.length()); } } finally { writer.close(); } } finally { zf.close(); } try (ZipFile zf = new ZipFile(zipFileName); BufferedWriter writer = Files.newBufferedWriter(outputPath, charset)) { for (ZipEntry entry : Collections.list(zf.entries())) { String entryName = entry.getName() + newLine; writer.write(entryName, 0, entryName.length()); } }
List<Integer> list = new ArrayList<Integer>(); Map<String, List<String>> bag; bag =
new HashMap<String, List<String>>(); List<Integer> list = new ArrayList<>(); Map<String, List<String>> bag; bag = new HashMap<>();
String[] array = {"おおさか", "なごや", "ふくおか"}; for (String name :
array) { switch (name) { case "なごや": System.out.println("こわい"); break; default: System.out.println("こわくない"); } } • • •
try { FileInputStream is = new FileInputStream(new File("")); Document doc
= DocumentBuilderFactory.newInstance() .newDocumentBuilder() .parse(is); } catch (IOException e) { // 例外処理 } catch (ParserConfigurationException e) { // 例外処理 } catch (SAXException e) { // 例外処理 } try { FileInputStream is = new FileInputStream(new File("")); Document doc = DocumentBuilderFactory.newInstance() .newDocumentBuilder() .parse(is); } catch (IOException ex) { // IO系例外処理 } catch (ParserConfigurationException | SAXException ex) { // XML系例外処理 } • •
final int[] phases = { 0b00110001, 0b01100010, 0b11000100, 0b10001001, 0b00010011,
0b00100110, 0b01001100, 0b10011000 }; final int[] phases = { Integer.parseInt("00110001", 2), Integer.parseInt("01100010", 2), Integer.parseInt("11000100", 2), Integer.parseInt("10001001", 2), Integer.parseInt("00010011", 2), Integer.parseInt("00100110", 2), Integer.parseInt("01001100", 2), Integer.parseInt("10011000", 2) }; int bin = 0b00_11_01_01_01_01; int oct = 0123_4567; int hex = 0xCAFE_BABE;
• • • • • List<Integer> list = #[1, 2,
3]; Set<Integer> set = #[1, 2, 3]; Map<String, Integer> map = #{ "foo": 1, "bar": 2 }; int[] array = {1, 2, 3};
public Foo(Object bar, Object[] buz) { this.bar = Objects.requireNonNull(bar); this.buz
= Objects.requireNonNull(buz, "buzはnullダメ"); } @Override public boolean equals(Object o) { if (o == null || o instanceof Foo) return false; Foo that = (Foo) o; return Objects.equals(this.bar, that.bar) && Objects.deepEquals(this.buz, that.buz); } @Override public int hashCode() { return Objects.hash(this.bar, this.buz); } • •
// Windows ¥r¥n, Linux ¥n, 昔のMac ¥r String nicerNewLine =
System.lineSeparator(); // Windows ¥r¥n, Linux ¥n, 昔のMac ¥r String newLine = System.getProperty("line.separator");
None
None
Path p1 = Paths.get("path/to/file"); assert !p1.isAbsolute(); Path p2 = Paths.get("/usr/bin/curl");
assert p2.isAbsolute(); Path p3 = Paths.get("path/foo"); Path 相対パス = p1.relativize(p3); /* ../../foo */ assert p1.getParent().endsWith("to"); assert p2.getRoot() != null; assert p1.getNameCount() == 3; assert p1.compareTo(p3) > 0;
Path link = Files.createLink(Paths.get("newFile"), Paths.get("existingFile")); List<String> eager = Files.readAllLines(Paths.get("hoge.txt"), Charset.forName("Shift_JIS"));
Reader reader = Files.newBufferedReader(Paths.get("hoge.txt"), Charset.forName("EUC-JP"));
DirectoryStream<Path> stream = Files.newDirectoryStream(Paths.get("画像フォルダ"), new DirectoryStream.Filter<Path>() { @Override public boolean
accept(final Path entry) throws IOException { return !Files.isDirectory(entry); } }); for (Path 画像 : stream){ // 何か }
Path bar = FileSystems.getDefault().getPath("foo/bar"); WatchService watchService = FileSystems.getDefault().newWatchService(); bar.register(watchService, StandardWatchEventKinds.ENTRY_CREATE,
StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_DELETE); while (!Thread.currentThread().isInterrupted()) { System.out.println("監視中..."); WatchKey watchKey = watchService.take(); if (watchKey.isValid()) { for (WatchEvent<?> event : watchKey.pollEvents()) { System.out.printf("イベント発生: %s", event.kind()); Path context = FileSystems.getDefault().getPath("¥¥" + event.context()); process(context, event); } } }
• • • •
None
None
None
1 2 3 4 5 • • • • •
• • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • • •
None
import java.awt.event.*; public class MyApp4 extends java.applet.Applet { public void
init() { this.addMouseListener(new MyMouseAdapter()); Button approveButton = new Button("承認"); approveButton.addActionListener(new ActionListener() { @Override public void actionPerformed(final ActionEvent evt) { // 承認 // 承認 // 承認 } }); this.add(approveButton); } }
Button approveButton = new Button("承認"); approveButton.addActionListener(evt -> { // do
something !! });
Collections.sort(names, new Comparator<String>() { @Override public int compare(final String a,
final String b) { return 0/*ここに比較ロジックが入ります*/; } }); 引数 -> 処理
BinaryOperator<String> longer = (String a, String b) -> { return
a.length() >= b.length() ? a : b; }; longer = (a, b) -> { return a.length() >= b.length() ? a : b; }; longer = (a, b) -> a.length() >= b.length() ? a : b; supplier = () -> Math.random(); toSet = arg -> Collections.singleton(arg);
Set<Lang> langs = EnumSet.of(JAVA, SCALA, CLOJURE, C_SHARP, F_SHARP, OCAML, RUBY,
PYTHON, HASKELL, JAVASCRIPT); List<String> collect = langs.stream() .filter(lang -> lang.isStaticallyTyped()) .map(lang -> lang.displayName()) .sorted() .collect(toList());
Set<Lang> langs = … List<String> collect = langs.stream() .filter(lang ->
lang.isStaticallyTyped()) • • interface Collection<E> { default Stream<E> stream() { return …; } }
interface Worker { default void work() {…} } interface Person
{ default void eat() {…} default void play() {…} default void sleep() {…} } class Programmer implements Worker, Person { public void aDayInTheLife() { this.eat(); if (Today.isWeekday()) { this.work(); } else { this.play(); } this.sleep(); } }
public String foo(User user) { if (user == null) {
return "不明なユーザ"; } else { return user.name(); } } public String bar(Optional<User> user) { return user.map(user_ -> user_.name()) .orElse("不明なユーザ"); } public Optional<User> find(long id) { User user = hoge(id); return Optional.ofNullable(user); }
None
• • • • • •
None
None