工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> Java

Java 8 完全クイックリファレンス:全新機能を網羅した決定版ガイド

Java 8 - 概要

JAVA 8は、Javaプログラミング言語開発における主要な機能リリースです。初版は2014年3月18日にリリースされました。Java 8のリリースにより、関数型プログラミングのサポート、新しいJavaScriptエンジン、日付時刻操作の新API、新しいストリーミングAPIなどが提供されるようになりました。

新機能

以下のコードスニペットをご覧ください。

Live Demo
import java.util.Collections;
import java.util.List;
import java.util.ArrayList;
import java.util.Comparator;

public class Java8Tester {
    public static void main(String args[]) {
        List<String> names1 = new ArrayList<String>();
        names1.add("Mahesh ");
        names1.add("Suresh ");
        names1.add("Ramesh ");
        names1.add("Naresh ");
        names1.add("Kalpesh ");
        
        List<String> names2 = new ArrayList<String>();
        names2.add("Mahesh ");
        names2.add("Suresh ");
        names2.add("Ramesh ");
        names2.add("Naresh ");
        names2.add("Kalpesh ");
        
        Java8Tester tester = new Java8Tester();
        System.out.println("Sort using Java 7 syntax: ");
        tester.sortUsingJava7(names1);
        System.out.println(names1);
        
        System.out.println("Sort using Java 8 syntax: ");
        tester.sortUsingJava8(names2);
        System.out.println(names2);
    }
    
    // Java 7でのソート
    private void sortUsingJava7(List<String> names) {
        Collections.sort(names, new Comparator<String>() {
            @Override
            public int compare(String s1, String s2) {
                return s1.compareTo(s2);
            }
        });
    }
    
    // Java 8でのソート
    private void sortUsingJava8(List<String> names) {
        Collections.sort(names, (s1, s2) -> s1.compareTo(s2));
    }
}

プログラムを実行すると以下の結果が得られます:

Sort using Java 7 syntax: 
[ Kalpesh Mahesh Naresh Ramesh Suresh ]
Sort using Java 8 syntax: 
[ Kalpesh Mahesh Naresh Ramesh Suresh ]

ここでsortUsingJava8()メソッドは、ソート基準を取得するためにラムダ式をパラメータとしてsort関数に渡しています。

Java 8 - 環境構築

ローカル環境構築

Javaプログラミング言語の独自環境を構築したい場合、このセクションがプロセス全体をガイドします。以下の手順に従ってJava環境を設定してください。

Java SEは以下のリンクから無料でダウンロードできます:

https://www.oracle.com/technetwork/java/javase/downloads/index-jsp-138363.html

お使いのオペレーティングシステムに基づいてバージョンをダウンロードしてください。

Javaのダウンロード手順に従い、.exeを実行してマシンにJavaをインストールします。マシンにJavaをインストールしたら、正しいインストールディレクトリを指すように環境変数を設定する必要があります。

Windows 2000/XPでのパス設定

c:\Program Files\java\jdkディレクトリにJavaをインストールしたと仮定します:

Windows 95/98/MEでのパス設定

c:\Program Files\java\jdkディレクトリにJavaをインストールしたと仮定します:

Linux, UNIX, Solaris, FreeBSDでのパス設定

環境変数PATHは、Javaバイナリがインストールされている場所を指すように設定してください。不明な場合はシェルのドキュメントを参照してください。

例えばbashをシェルとして使用している場合、'.bashrc'の末尾に以下の行を追加します:
export PATH=/path/to/java:$PATH

人気のJavaエディタ

Javaプログラムを書くにはテキストエディタが必要です。市場にはより洗練されたIDEも多数あります。現時点では以下のいずれかを検討できます:

Java 8 - ラムダ式

ラムダ式はJava 8で導入され、Java 8最大の機能と謳われています。ラムダ式は関数型プログラミングを容易にし、開発を大幅に簡素化します。

構文

ラムダ式は以下の構文で特徴づけられます:

parameter -> expression body

ラムダ式の重要な特徴は以下の通りです:

ラムダ式の例

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
public class Java8Tester {
    public static void main(String args[]) {
        Java8Tester tester = new Java8Tester();
        
        // 型宣言あり
        MathOperation addition = (int a, int b) -> a + b;
        // 型宣言なし
        MathOperation subtraction = (a, b) -> a - b;
        // return文と中括弧あり
        MathOperation multiplication = (int a, int b) -> { return a * b; };
        // return文なし、中括弧なし
        MathOperation division = (int a, int b) -> a / b;
        
        System.out.println("10 + 5 = " + tester.operate(10, 5, addition));
        System.out.println("10 - 5 = " + tester.operate(10, 5, subtraction));
        System.out.println("10 x 5 = " + tester.operate(10, 5, multiplication));
        System.out.println("10 / 5 = " + tester.operate(10, 5, division));
        
        // 丸括弧なし
        GreetingService greetService1 = message -> System.out.println("Hello " + message);
        // 丸括弧あり
        GreetingService greetService2 = (message) -> System.out.println("Hello " + message);
        
        greetService1.sayMessage("Mahesh");
        greetService2.sayMessage("Suresh");
    }
    
    interface MathOperation {
        int operation(int a, int b);
    }
    
    interface GreetingService {
        void sayMessage(String message);
    }
    
    private int operate(int a, int b, MathOperation mathOperation) {
        return mathOperation.operation(a, b);
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の出力が生成されます:

10 + 5 = 15
10 - 5 = 5
10 x 5 = 50
10 / 5 = 2
Hello Mahesh
Hello Suresh

上記の例で考慮すべき重要なポイント:

スコープ

ラムダ式を使用すると、任意のfinal変数または実質的にfinalな変数(一度だけ代入される変数)を参照できます。変数に2回目の値が代入されると、ラムダ式はコンパイルエラーをスローします。

スコープの例

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
public class Java8Tester {
    final static String salutation = "Hello! ";
    
    public static void main(String args[]) {
        GreetingService greetService1 = message -> System.out.println(salutation + message);
        greetService1.sayMessage("Mahesh");
    }
    
    interface GreetingService {
        void sayMessage(String message);
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の出力が生成されます:

Hello! Mahesh

Java 8 - メソッド参照

メソッド参照は、メソッドを名前で指し示すのに役立ちます。メソッド参照は"::"シンボルで記述されます。メソッド参照は以下のタイプのメソッドを指し示すために使用できます:

メソッド参照の例

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

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

public class Java8Tester {
    public static void main(String args[]) {
        List names = new ArrayList();
        names.add("Mahesh");
        names.add("Suresh");
        names.add("Ramesh");
        names.add("Naresh");
        names.add("Kalpesh");
        names.forEach(System.out::println);
    }
}

ここではSystem.out::printlnメソッドを静的メソッド参照として渡しています。

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の出力が生成されます:

Mahesh
Suresh
Ramesh
Naresh
Kalpesh

Java 8 - 関数型インターフェース

関数型インターフェースは単一の機能を示します。例えば、単一メソッド'compareTo'を持つComparableインターフェースは比較目的で使用されます。Java 8では、ラムダ式で広く使用される多くの関数型インターフェースが定義されています。以下はjava.util.functionパッケージで定義されている関数型インターフェースのリストです。

番号 インターフェースと説明
1

BiConsumer<T,U>

2つの入力引数を受け取り、結果を返さない操作を表します。

2

BiFunction<T,U,R>

2つの引数を受け取り、結果を生成する関数を表します。

3

BinaryOperator<T>

同じ型の2つのオペランドに対する操作を表し、オペランドと同じ型の結果を生成します。

4

BiPredicate<T,U>

2つの引数を持つ述語(真偽値関数)を表します。

5

BooleanSupplier

真偽値の結果の供給元を表します。

6

Consumer<T>

単一の入力引数を受け取り、結果を返さない操作を表します。

7

DoubleBinaryOperator

2つのdouble値オペランドに対する操作を表し、double値の結果を生成します。

8

DoubleConsumer

単一のdouble値引数を受け取り、結果を返さない操作を表します。

9

DoubleFunction<R>

double値引数を受け取り、結果を生成する関数を表します。

10

DoublePredicate

1つのdouble値引数を持つ述語(真偽値関数)を表します。

11

DoubleSupplier

double値の結果の供給元を表します。

12

DoubleToIntFunction

double値引数を受け取り、int値の結果を生成する関数を表します。

13

DoubleToLongFunction

double値引数を受け取り、long値の結果を生成する関数を表します。

14

DoubleUnaryOperator

単一のdouble値オペランドに対する操作を表し、double値の結果を生成します。

15

Function<T,R>

1つの引数を受け取り、結果を生成する関数を表します。

16

IntBinaryOperator

2つのint値オペランドに対する操作を表し、int値の結果を生成します。

17

IntConsumer

単一のint値引数を受け取り、結果を返さない操作を表します。

18

IntFunction<R>

int値引数を受け取り、結果を生成する関数を表します。

19

IntPredicate

1つのint値引数を持つ述語(真偽値関数)を表します。

20

IntSupplier

int値の結果の供給元を表します。

21

IntToDoubleFunction

int値引数を受け取り、double値の結果を生成する関数を表します。

22

IntToLongFunction

int値引数を受け取り、long値の結果を生成する関数を表します。

23

IntUnaryOperator

単一のint値オペランドに対する操作を表し、int値の結果を生成します。

24

LongBinaryOperator

2つのlong値オペランドに対する操作を表し、long値の結果を生成します。

25

LongConsumer

単一のlong値引数を受け取り、結果を返さない操作を表します。

26

LongFunction<R>

long値引数を受け取り、結果を生成する関数を表します。

27

LongPredicate

1つのlong値引数を持つ述語(真偽値関数)を表します。

28

LongSupplier

long値の結果の供給元を表します。

29

LongToDoubleFunction

long値引数を受け取り、double値の結果を生成する関数を表します。

30

LongToIntFunction

long値引数を受け取り、int値の結果を生成する関数を表します。

31

LongUnaryOperator

単一のlong値オペランドに対する操作を表し、long値の結果を生成します。

32

ObjDoubleConsumer<T>

オブジェクト値とdouble値の引数を受け取り、結果を返さない操作を表します。

33

ObjIntConsumer<T>

オブジェクト値とint値の引数を受け取り、結果を返さない操作を表します。

34

ObjLongConsumer<T>

オブジェクト値とlong値の引数を受け取り、結果を返さない操作を表します。

35

Predicate<T>

1つの引数を持つ述語(真偽値関数)を表します。

36

Supplier<T>

結果の供給元を表します。

37

ToDoubleBiFunction<T,U>

2つの引数を受け取り、double値の結果を生成する関数を表します。

38

ToDoubleFunction<T>

double値の結果を生成する関数を表します。

39

ToIntBiFunction<T,U>

2つの引数を受け取り、int値の結果を生成する関数を表します。

40

ToIntFunction<T>

int値の結果を生成する関数を表します。

41

ToLongBiFunction<T,U>

2つの引数を受け取り、long値の結果を生成する関数を表します。

42

ToLongFunction<T>

long値の結果を生成する関数を表します。

43

UnaryOperator<T>

単一のオペランドに対する操作を表し、オペランドと同じ型の結果を生成します。

関数型インターフェースの例

Predicate<T>インターフェースは、test(Object)メソッドを持ってBoolean値を返す関数型インターフェースです。このインターフェースは、オブジェクトがtrueまたはfalseであるかをテストすることを意味します。

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class Java8Tester {
    public static void main(String args[]) {
        List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        
        // Predicate<Integer> predicate = n -> true
        // nはPredicateインターフェースのtestメソッドにパラメータとして渡される
        // testメソッドはnの値に関わらず常にtrueを返す
        System.out.println("Print all numbers:");
        // nをパラメータとして渡す
        eval(list, n -> true);
        
        // Predicate<Integer> predicate1 = n -> n%2 == 0
        // nはPredicateインターフェースのtestメソッドにパラメータとして渡される
        // n%2が0になる場合、testメソッドはtrueを返す
        System.out.println("Print even numbers:");
        eval(list, n -> n % 2 == 0);
        
        // Predicate<Integer> predicate2 = n -> n > 3
        // nはPredicateインターフェースのtestメソッドにパラメータとして渡される
        // nが3より大きい場合、testメソッドはtrueを返す
        System.out.println("Print numbers greater than 3:");
        eval(list, n -> n > 3);
    }
    
    public static void eval(List<Integer> list, Predicate<Integer> predicate) {
        for (Integer n : list) {
            if (predicate.test(n)) {
                System.out.println(n + " ");
            }
        }
    }
}

ここでは、単一の入力を受け取りBooleanを返すPredicateインターフェースを渡しています。

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の出力が生成されます:

Print all numbers:
1 2 3 4 5 6 7 8 9
Print even numbers:
2 4 6 8
Print numbers greater than 3:
4 5 6 7 8 9

Java 8 - デフォルトメソッド

Java 8では、インターフェースにおけるデフォルトメソッド実装という新しい概念が導入されました。この機能は後方互換性のために追加され、古いインターフェースがJava 8のラムダ式機能を活用できるようになりました。

例えば、'List'や'Collection'インターフェースには'forEach'メソッドの宣言がありません。このようなメソッドを単純に追加すると、コレクションフレームワークの実装が単純に壊れてしまいます。Java 8ではデフォルトメソッドを導入することで、List/CollectionインターフェースがforEachメソッドのデフォルト実装を持てるようになり、これらのインターフェースを実装するクラスは同じものを実装する必要がなくなりました。

構文

public interface vehicle {
    default void print() {
        System.out.println("I am a vehicle!");
    }
}

複数のデフォルトメソッド

インターフェースにデフォルト関数がある場合、同じデフォルトメソッドを持つ2つのインターフェースをクラスが実装する可能性があります。以下のコードはこの曖昧さを解決する方法を説明しています。

public interface vehicle {
    default void print() {
        System.out.println("I am a vehicle!");
    }
}
public interface fourWheeler {
    default void print() {
        System.out.println("I am a four wheeler!");
    }
}

最初の解決策は、デフォルト実装をオーバーライドする独自のメソッドを作成することです。

public class car implements vehicle, fourWheeler {
    public void print() {
        System.out.println("I am a four wheeler car vehicle!");
    }
}

2番目の解決策は、superを使用して指定されたインターフェースのデフォルトメソッドを呼び出すことです。

public class car implements vehicle, fourWheeler {
    public void print() {
        vehicle.super.print();
    }
}

静的デフォルトメソッド

Java 8以降、インターフェースは静的ヘルパーメソッドを持つこともできます。

public interface vehicle {
    default void print() {
        System.out.println("I am a vehicle!");
    }
    static void blowHorn() {
        System.out.println("Blowing horn!!!");
    }
}

デフォルトメソッドの例

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
public class Java8Tester {
    public static void main(String args[]) {
        Vehicle vehicle = new Car();
        vehicle.print();
    }
}

interface Vehicle {
    default void print() {
        System.out.println("I am a vehicle!");
    }
    static void blowHorn() {
        System.out.println("Blowing horn!!!");
    }
}

interface FourWheeler {
    default void print() {
        System.out.println("I am a four wheeler!");
    }
}

class Car implements Vehicle, FourWheeler {
    public void print() {
        Vehicle.super.print();
        FourWheeler.super.print();
        Vehicle.blowHorn();
        System.out.println("I am a car!");
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の出力が生成されます:

I am a vehicle!
I am a four wheeler!
Blowing horn!!!
I am a car!

Java 8 - ストリーム

ストリームはJava 8で導入された新しい抽象レイヤーです。ストリームを使用すると、SQL文と同様に宣言的な方法でデータを処理できます。例えば、以下のSQL文を考えてみてください:

SELECT max(salary), employee_id, employee_name FROM Employee

上記のSQL式は、開発者側で計算を行うことなく、最高給与の従業員の詳細を自動的に返します。Javaのコレクションフレームワークを使用する場合、開発者はループを使用し、繰り返しチェックを行う必要があります。もう一つの懸念は効率性です。マルチコアプロセッサが容易に利用できる現在、Java開発者は並列コード処理を記述する必要がありますが、これはかなりエラーを起こしやすい作業です。

このような問題を解決するため、Java 8ではストリームの概念が導入され、開発者がデータを宣言的に処理し、マルチコアアーキテクチャを活用できるようになりました。そのために特定のコードを書く必要はありません。

ストリームとは

ストリームは、ソースからのオブジェクトのシーケンスを表し、集約操作をサポートします。ストリームの特徴は以下の通りです:

ストリームの生成

Java 8では、Collectionインターフェースにストリームを生成する2つのメソッドがあります:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

forEach

ストリームには、ストリームの各要素を反復処理する新しいメソッド'forEach'が提供されています。以下のコードセグメントは、forEachを使用して10個の乱数を出力する方法を示しています:

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

map

'map'メソッドは、各要素を対応する結果にマッピングするために使用されます。以下のコードセグメントは、mapを使用して数値のユニークな平方を出力します:

List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
// ユニークな平方のリストを取得
List<Integer> squaresList = numbers.stream().map(i -> i*i).distinct().collect(Collectors.toList());

filter

'filter'メソッドは、基準に基づいて要素を除外するために使用されます。以下のコードセグメントは、filterを使用して空文字列の数を出力します:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 空文字列の数を取得
int count = strings.stream().filter(string -> string.isEmpty()).count();

limit

'limit'メソッドは、ストリームのサイズを縮小するために使用されます。以下のコードセグメントは、limitを使用して10個の乱数を出力する方法を示しています:

Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

sorted

'sorted'メソッドは、ストリームをソートするために使用されます。以下のコードセグメントは、10個の乱数をソート順で出力する方法を示しています:

Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);

並列処理

parallelStreamは並列処理のためのstreamの代替です。以下のコードセグメントは、parallelStreamを使用して空文字列の数を出力します:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
// 空文字列の数を取得
long count = strings.parallelStream().filter(string -> string.isEmpty()).count();

順次ストリームと並列ストリームの切り替えは非常に簡単です。

Collectors

Collectorsは、ストリームの要素に対する処理結果を結合するために使用されます。Collectorsはリストや文字列を返すために使用できます:

List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("Filtered List: " + filtered);
String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("Merged String: " + mergedString);

統計

Java 8では、ストリーム処理時にすべての統計を計算するための統計コレクターが導入されました:

List numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("Highest number in List : " + stats.getMax());
System.out.println("Lowest number in List : " + stats.getMin());
System.out.println("Sum of all numbers : " + stats.getSum());
System.out.println("Average of all numbers : " + stats.getAverage());

ストリームの例

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
import java.util.ArrayList;
import java.util.Arrays;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;
import java.util.Map;

public class Java8Tester {
    public static void main(String args[]) {
        System.out.println("Using Java 7: ");
        // 空文字列のカウント
        List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
        System.out.println("List: " + strings);
        long count = getCountEmptyStringUsingJava7(strings);
        System.out.println("Empty Strings: " + count);
        count = getCountLength3UsingJava7(strings);
        System.out.println("Strings of length 3: " + count);
        // 空文字列を除去
        List<String> filtered = deleteEmptyStringsUsingJava7(strings);
        System.out.println("Filtered List: " + filtered);
        // 空文字列を除去してカンマで結合
        String mergedString = getMergedStringUsingJava7(strings, ", ");
        System.out.println("Merged String: " + mergedString);
        List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
        // 異なる数値の平方のリストを取得
        List<Integer> squaresList = getSquares(numbers);
        System.out.println("Squares List: " + squaresList);
        List<Integer> integers = Arrays.asList(1,2,13,4,15,6,17,8,19);
        System.out.println("List: " + integers);
        System.out.println("Highest number in List : " + getMax(integers));
        System.out.println("Lowest number in List : " + getMin(integers));
        System.out.println("Sum of all numbers : " + getSum(integers));
        System.out.println("Average of all numbers : " + getAverage(integers));
        System.out.println("Random Numbers: ");
        // 10個の乱数を出力
        Random random = new Random();
        for (int i = 0; i < 10; i++) {
            System.out.println(random.nextInt());
        }
        System.out.println("Using Java 8: ");
        System.out.println("List: " + strings);
        count = strings.stream().filter(string -> string.isEmpty()).count();
        System.out.println("Empty Strings: " + count);
        count = strings.stream().filter(string -> string.length() == 3).count();
        System.out.println("Strings of length 3: " + count);
        filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
        System.out.println("Filtered List: " + filtered);
        mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
        System.out.println("Merged String: " + mergedString);
        squaresList = numbers.stream().map(i -> i*i).distinct().collect(Collectors.toList());
        System.out.println("Squares List: " + squaresList);
        System.out.println("List: " + integers);
        IntSummaryStatistics stats = integers.stream().mapToInt((x) -> x).summaryStatistics();
        System.out.println("Highest number in List : " + stats.getMax());
        System.out.println("Lowest number in List : " + stats.getMin());
        System.out.println("Sum of all numbers : " + stats.getSum());
        System.out.println("Average of all numbers : " + stats.getAverage());
        System.out.println("Random Numbers: ");
        random.ints().limit(10).sorted().forEach(System.out::println);
        // 並列処理
        count = strings.parallelStream().filter(string -> string.isEmpty()).count();
        System.out.println("Empty Strings: " + count);
    }
    
    // 以下、Java 7スタイルの実装メソッド群(省略)
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の結果が出力されます:

Using Java 7:
List: [abc, , bc, efg, abcd, , jkl]
Empty Strings: 2
Strings of length 3: 3
Filtered List: [abc, bc, efg, abcd, jkl]
Merged String: abc, bc, efg, abcd, jkl
Squares List: [9, 4, 49, 25]
List: [1, 2, 13, 4, 15, 6, 17, 8, 19]
Highest number in List : 19
Lowest number in List : 1
Sum of all numbers : 85
Average of all numbers : 9
Random Numbers:
-1279735475
903418352
-1133928044
-1571118911
628530462
18407523
-881538250
-718932165
270259229
421676854
Using Java 8:
List: [abc, , bc, efg, abcd, , jkl]
Empty Strings: 2
Strings of length 3: 3
Filtered List: [abc, bc, efg, abcd, jkl]
Merged String: abc, bc, efg, abcd, jkl
Squares List: [9, 4, 49, 25]
List: [1, 2, 13, 4, 15, 6, 17, 8, 19]
Highest number in List : 19
Lowest number in List : 1
Sum of all numbers : 85
Average of all numbers : 9.444444444444445
Random Numbers:
-1009474951
-551240647
-2484714
181614550
933444268
1227850416
1579250773
1627454872
1683033687
1798939493
Empty Strings: 2

Java 8 - Optionalクラス

Optionalは、nullでないオブジェクトを格納するためのコンテナオブジェクトです。Optionalオブジェクトは、値が存在しない状態を表現するために使用されます。このクラスには、nullチェックを行う代わりに、値を「利用可能」または「利用不可」として扱うためのさまざまなユーティリティメソッドが用意されています。Java 8で導入され、GuavaのOptionalと同様の機能を提供します。

クラス宣言

以下はjava.util.Optional<T>クラスの宣言です:

public final class Optional<T> extends Object

クラスメソッド

番号 メソッドと説明
1

static <T> Optional<T> empty()

空のOptionalインスタンスを返します。

2

boolean equals(Object obj)

他のオブジェクトがこのOptionalと「等しい」かどうかを示します。

3

Optional<T> filter(Predicate<? super T> predicate)

値が存在し、その値が指定された述語と一致する場合、その値を記述するOptionalを返し、そうでない場合は空のOptionalを返します。

4

<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)

値が存在する場合、提供されたOptionalを返すマッピング関数を適用し、その結果を返します。値が存在しない場合は空のOptionalを返します。

5

T get()

このOptionalに値が存在する場合、その値を返し、そうでない場合はNoSuchElementExceptionをスローします。

6

int hashCode()

値が存在する場合はその値のハッシュコードを、存在しない場合は0を返します。

7

void ifPresent(Consumer<? super T> consumer)

値が存在する場合、指定されたコンシューマをその値で呼び出し、存在しない場合は何もしません。

8

boolean isPresent()

値が存在する場合はtrueを、そうでない場合はfalseを返します。

9

<U> Optional<U> map(Function<? super T, ? extends U> mapper)

値が存在する場合、提供されたマッピング関数を適用し、結果がnullでない場合はその結果を記述するOptionalを返します。

10

static <T> Optional<T> of(T value)

指定された非null値を持つOptionalを返します。

11

static <T> Optional<T> ofNullable(T value)

指定された値が非nullの場合はその値を記述するOptionalを、nullの場合は空のOptionalを返します。

12

T orElse(T other)

値が存在する場合はその値を、存在しない場合はotherを返します。

13

T orElseGet(Supplier<? extends T> other)

値が存在する場合はその値を、存在しない場合はotherを呼び出し、その呼び出しの結果を返します。

14

<X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier)

値が存在する場合はその値を返し、存在しない場合は提供されたサプライヤによって作成される例外をスローします。

15

String toString()

デバッグに適した、空でないこのOptionalの文字列表現を返します。

このクラスは以下のクラスからメソッドを継承しています:

Optionalの例

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
import java.util.Optional;

public class Java8Tester {
    public static void main(String args[]) {
        Java8Tester java8Tester = new Java8Tester();
        Integer value1 = null;
        Integer value2 = new Integer(10);
        // Optional.ofNullable - 渡されたパラメータがnullでも許可される
        Optional<Integer> a = Optional.ofNullable(value1);
        // Optional.of - 渡されたパラメータがnullの場合、NullPointerExceptionをスロー
        Optional<Integer> b = Optional.of(value2);
        System.out.println(java8Tester.sum(a, b));
    }
    
    public Integer sum(Optional<Integer> a, Optional<Integer> b) {
        // Optional.isPresent - 値が存在するかどうかをチェック
        System.out.println("First parameter is present: " + a.isPresent());
        System.out.println("Second parameter is present: " + b.isPresent());
        // Optional.orElse - 値が存在する場合はその値を、存在しない場合はデフォルト値を返す
        Integer value1 = a.orElse(new Integer(0));
        // Optional.get - 値を取得、値が存在している必要がある
        Integer value2 = b.get();
        return value1 + value2;
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の出力が生成されます:

First parameter is present: false
Second parameter is present: true
10

Java 8 - Nashorn JavaScript

Java 8では、既存のRhinoに代わって、大幅に改善されたJavaScriptエンジン「Nashorn」が導入されました。Nashornはコードをメモリ内で直接コンパイルし、バイトコードをJVMに渡すため、2〜10倍の性能向上を実現しています。NashornはJava 7で導入されたinvokedynamic機能を活用してパフォーマンスを向上させています。

jjs

Nashornエンジン用に、Java 8ではコンソールでJavaScriptコードを実行するための新しいコマンドラインツールjjsが導入されました。

JavaScriptファイルの解釈実行

sample.jsファイルを作成し、c:\> JAVAフォルダに保存します。

sample.js

print('Hello World!');

コンソールを開き、以下のコマンドを使用します:

C:\JAVA>jjs sample.js

以下の出力が生成されます:

Hello World!

jjsのインタラクティブモード

コンソールを開き、以下のコマンドを使用します:

C:\JAVA>jjs
jjs> print("Hello, World!")
Hello, World!
jjs> quit()
>>

引数の渡し方

コンソールを開き、以下のコマンドを使用します:

C:\JAVA> jjs -- a b c
jjs> print('letters: ' + arguments.join(", "))
letters: a, b, c
jjs>

JavaからJavaScriptの呼び出し

ScriptEngineManagerを使用して、JavaScriptコードをJava内で呼び出し、解釈実行できます。

例

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
import javax.script.ScriptException;

public class Java8Tester {
    public static void main(String args[]) {
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn");
        String name = "Mahesh";
        Integer result = null;
        try {
            nashorn.eval("print('" + name + "')");
            result = (Integer) nashorn.eval("10 + 2");
        } catch (ScriptException e) {
            System.out.println("Error executing script: " + e.getMessage());
        }
        System.out.println(result.toString());
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の結果が出力されます:

Mahesh
12

JavaScriptからJavaの呼び出し

以下の例は、JavaScript内でJavaクラスをインポートして使用する方法を説明しています。

sample.jsを作成し、c:\> JAVAフォルダに保存します。

sample.js

var BigDecimal = Java.type('java.math.BigDecimal');
function calculate(amount, percentage) {
    var result = new BigDecimal(amount).multiply(new BigDecimal(percentage)).divide(
        new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_EVEN);
    return result.toPlainString();
}
var result = calculate(568000000000000000023, 13.9);
print(result);

コンソールで以下のコマンドを使用します:

C:\JAVA>jjs sample.js

以下の出力が生成されます:

78952000000000000003.20

Java 8 - 新Date/Time API

Java 8では、従来の日付時刻APIの以下の欠点を解消する新しいDate-Time APIが導入されました。

Java 8では、新しい日付時刻APIがjava.timeパッケージの下に導入されました。以下はjava.timeパッケージで導入された重要なクラスの一部です:

Local Date-Time API

LocalDate/LocalTimeおよびLocalDateTimeクラスは、タイムゾーンが不要な開発を簡素化します。実際に動作を見てみましょう。

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.LocalDateTime;
import java.time.Month;

public class Java8Tester {
    public static void main(String args[]) {
        Java8Tester java8tester = new Java8Tester();
        java8tester.testLocalDateTime();
    }
    
    public void testLocalDateTime() {
        // 現在の日付と時刻を取得
        LocalDateTime currentTime = LocalDateTime.now();
        System.out.println("Current DateTime: " + currentTime);
        LocalDate date1 = currentTime.toLocalDate();
        System.out.println("date1: " + date1);
        Month month = currentTime.getMonth();
        int day = currentTime.getDayOfMonth();
        int seconds = currentTime.getSecond();
        System.out.println("Month: " + month + " day: " + day + " seconds: " + seconds);
        LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012);
        System.out.println("date2: " + date2);
        // 2014年12月12日
        LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12);
        System.out.println("date3: " + date3);
        // 22時15分
        LocalTime date4 = LocalTime.of(22, 15);
        System.out.println("date4: " + date4);
        // 文字列をパース
        LocalTime date5 = LocalTime.parse("20:15:30");
        System.out.println("date5: " + date5);
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の出力が生成されます:

Current DateTime: 2014-12-09T11:00:45.457
date1: 2014-12-09
Month: DECEMBER day: 9 seconds: 45
date2: 2012-12-10T11:00:45.457
date3: 2014-12-12
date4: 22:15
date5: 20:15:30

Zoned Date-Time API

タイムゾーンを考慮する必要がある場合は、Zoned date-time APIを使用します。実際の動作を見てみましょう。

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
import java.time.ZonedDateTime;
import java.time.ZoneId;

public class Java8Tester {
    public static void main(String args[]) {
        Java8Tester java8tester = new Java8Tester();
        java8tester.testZonedDateTime();
    }
    
    public void testZonedDateTime() {
        // 現在の日付と時刻を取得
        ZonedDateTime date1 = ZonedDateTime.parse("2007-12-03T10:15:30+05:30[Asia/Karachi]");
        System.out.println("date1: " + date1);
        ZoneId id = ZoneId.of("Europe/Paris");
        System.out.println("ZoneId: " + id);
        ZoneId currentZone = ZoneId.systemDefault();
        System.out.println("CurrentZone: " + currentZone);
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の出力が生成されます:

date1: 2007-12-03T10:15:30+05:00[Asia/Karachi]
ZoneId: Europe/Paris
CurrentZone: Etc/UTC

ChronoUnit列挙型

Java 8では、旧APIで日、月などを表すために使用されていた整数値を置き換えるため、java.time.temporal.ChronoUnit列挙型が追加されました。実際の動作を見てみましょう。

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;

public class Java8Tester {
    public static void main(String args[]) {
        Java8Tester java8tester = new Java8Tester();
        java8tester.testChromoUnits();
    }
    
    public void testChromoUnits() {
        // 現在の日付を取得
        LocalDate today = LocalDate.now();
        System.out.println("Current date: " + today);
        // 現在の日付に1週間加算
        LocalDate nextWeek = today.plus(1, ChronoUnit.WEEKS);
        System.out.println("Next week: " + nextWeek);
        // 現在の日付に1ヶ月加算
        LocalDate nextMonth = today.plus(1, ChronoUnit.MONTHS);
        System.out.println("Next month: " + nextMonth);
        // 現在の日付に1年加算
        LocalDate nextYear = today.plus(1, ChronoUnit.YEARS);
        System.out.println("Next year: " + nextYear);
        // 現在の日付に10年加算
        LocalDate nextDecade = today.plus(1, ChronoUnit.DECADES);
        System.out.println("Date after ten year: " + nextDecade);
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の結果が出力されます:

Current date: 2014-12-10
Next week: 2014-12-17
Next month: 2015-01-10
Next year: 2015-12-10
Date after ten year: 2024-12-10

PeriodとDuration

Java 8では、時間の差を扱うための2つの専門クラスが導入されました:

実際の動作を見てみましょう。

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
import java.time.temporal.ChronoUnit;
import java.time.LocalDate;
import java.time.LocalTime;
import java.time.Duration;
import java.time.Period;

public class Java8Tester {
    public static void main(String args[]) {
        Java8Tester java8tester = new Java8Tester();
        java8tester.testPeriod();
        java8tester.testDuration();
    }
    
    public void testPeriod() {
        // 現在の日付を取得
        LocalDate date1 = LocalDate.now();
        System.out.println("Current date: " + date1);
        // 現在の日付に1ヶ月加算
        LocalDate date2 = date1.plus(1, ChronoUnit.MONTHS);
        System.out.println("Next month: " + date2);
        Period period = Period.between(date2, date1);
        System.out.println("Period: " + period);
    }
    
    public void testDuration() {
        LocalTime time1 = LocalTime.now();
        Duration twoHours = Duration.ofHours(2);
        LocalTime time2 = time1.plus(twoHours);
        Duration duration = Duration.between(time1, time2);
        System.out.println("Duration: " + duration);
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の出力が生成されます:

Current date: 2014-12-10
Next month: 2015-01-10
Period: P-1M
Duration: PT2H

Temporal Adjusters(時間調整子)

TemporalAdjusterは日付の計算を行うために使用されます。例えば、「月の第2土曜日」や「次の火曜日」を取得する場合などです。実際の動作を見てみましょう。

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
import java.time.LocalDate;
import java.time.temporal.TemporalAdjusters;
import java.time.DayOfWeek;

public class Java8Tester {
    public static void main(String args[]) {
        Java8Tester java8tester = new Java8Tester();
        java8tester.testAdjusters();
    }
    
    public void testAdjusters() {
        // 現在の日付を取得
        LocalDate date1 = LocalDate.now();
        System.out.println("Current date: " + date1);
        // 次の火曜日を取得
        LocalDate nextTuesday = date1.with(TemporalAdjusters.next(DayOfWeek.TUESDAY));
        System.out.println("Next Tuesday on: " + nextTuesday);
        // 来月の最初の日を取得
        LocalDate firstInYear = LocalDate.of(date1.getYear(), date1.getMonth(), 1);
        // 第2土曜日を取得
        LocalDate secondSaturday = firstInYear.with(TemporalAdjusters.nextOrSame(DayOfWeek.SATURDAY))
                                             .with(TemporalAdjusters.next(DayOfWeek.SATURDAY));
        System.out.println("Second Saturday on: " + secondSaturday);
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の結果が出力されます:

Current date: 2014-12-10
Next Tuesday on: 2014-12-16
Second Saturday on: 2014-12-13

後方互換性

元のDateおよびCalendarオブジェクトにtoInstant()メソッドが追加され、これらを新しいDate-Time APIに変換できるようになりました。ofInstant(Instant, ZoneId)メソッドを使用して、LocalDateTimeまたはZonedDateTimeオブジェクトを取得できます。実際の動作を見てみましょう。

任意のエディタで以下のJavaプログラムを作成してください(例:C:\> JAVA)。

Java8Tester.java

Live Demo
import java.time.LocalDateTime;
import java.time.ZonedDateTime;
import java.util.Date;
import java.time.Instant;
import java.time.ZoneId;

public class Java8Tester {
    public static void main(String args[]) {
        Java8Tester java8tester = new Java8Tester();
        java8tester.testBackwardCompatability();
    }
    
    public void testBackwardCompatability() {
        // 現在の日付を取得
        Date currentDate = new Date();
        System.out.println("Current date: " + currentDate);
        // 現在の日付のインスタントをミリ秒単位で取得
        Instant now = currentDate.toInstant();
        ZoneId currentZone = ZoneId.systemDefault();
        LocalDateTime localDateTime = LocalDateTime.ofInstant(now, currentZone);
        System.out.println("Local date: " + localDateTime);
        ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(now, currentZone);
        System.out.println("Zoned date: " + zonedDateTime);
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の出力が生成されます:

Current date: Wed Dec 10 05:44:06 UTC 2014
Local date: 2014-12-10T05:44:06.635
Zoned date: 2014-12-10T05:44:06.635Z[Etc/UTC]

Java 8 - Base64

Java 8では、ついにBase64が標準ライブラリとして搭載されました。Java 8にはBase64エンコーディング用の組み込みエンコーダとデコーダが用意されています。Java 8では、以下の3種類のBase64エンコーディングを使用できます:

ネストされたクラス

番号 ネストクラスと説明
1

static class Base64.Decoder

RFC 4648およびRFC 2045で指定されたBase64エンコーディングスキームを使用してバイトデータをデコードするデコーダを実装します。

2

static class Base64.Encoder

RFC 4648およびRFC 2045で指定されたBase64エンコーディングスキームを使用してバイトデータをエンコードするエンコーダを実装します。

メソッド

番号 メソッド名と説明
1

static Base64.Decoder getDecoder()

Basicタイプのbase64エンコーディングスキームを使用してデコードするBase64.Decoderを返します。

2

static Base64.Encoder getEncoder()

Basicタイプのbase64エンコーディングスキームを使用してエンコードするBase64.Encoderを返します。

3

static Base64.Decoder getMimeDecoder()

MIMEタイプのbase64デコーディングスキームを使用してデコードするBase64.Decoderを返します。

4

static Base64.Encoder getMimeEncoder()

MIMEタイプのbase64エンコーディングスキームを使用してエンコードするBase64.Encoderを返します。

5

static Base64.Encoder getMimeEncoder(int lineLength, byte[] lineSeparator)

指定された行長と行セパレータを使用して、MIMEタイプのbase64エンコーディングスキームでエンコードするBase64.Encoderを返します。

6

static Base64.Decoder getUrlDecoder()

URLおよびファイル名安全タイプのbase64エンコーディングスキームを使用してデコードするBase64.Decoderを返します。

7

static Base64.Encoder getUrlEncoder()

URLおよびファイル名安全タイプのbase64エンコーディングスキームを使用してエンコードするBase64.Encoderを返します。

継承メソッド

このクラスは以下のクラスからメソッドを継承しています:

Base64の例

任意のエディタで以下のJavaプログラムを作成してください(例:C:/> JAVA)。

Java8Tester.java

Live Demo
import java.util.Base64;
import java.util.UUID;
import java.io.UnsupportedEncodingException;

public class HelloWorld {
    public static void main(String args[]) {
        try {
            // Basicエンコーダでエンコード
            String base64encodedString = Base64.getEncoder().encodeToString(
                "TutorialsPoint?java8".getBytes("utf-8"));
            System.out.println("Base64 Encoded String (Basic) :" + base64encodedString);
            // デコード
            byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);
            System.out.println("Original String: " + new String(base64decodedBytes, "utf-8"));
            base64encodedString = Base64.getUrlEncoder().encodeToString(
                "TutorialsPoint?java8".getBytes("utf-8"));
            System.out.println("Base64 Encoded String (URL) :" + base64encodedString);
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < 10; ++i) {
                stringBuilder.append(UUID.randomUUID().toString());
            }
            byte[] mimeBytes = stringBuilder.toString().getBytes("utf-8");
            String mimeEncodedString = Base64.getMimeEncoder().encodeToString(mimeBytes);
            System.out.println("Base64 Encoded String (MIME) :" + mimeEncodedString);
        } catch (UnsupportedEncodingException e) {
            System.out.println("Error :" + e.getMessage());
        }
    }
}

実行結果の確認

javacコンパイラでコンパイルします:

C:\JAVA>javac Java8Tester.java

実行します:

C:\JAVA>java Java8Tester

以下の出力が生成されます:

Base64 Encoded String (Basic) :VHV0b3JpYWxzUG9pbnQ/amF2YTg=
Original String: TutorialsPoint?java8
Base64 Encoded String (URL) :VHV0b3JpYWxzUG9pbnQ_amF2YTg=
Base64 Encoded String (MIME) :YmU3NWY2ODktNGM5YS00ODlmLWI2MTUtZTVkOTk2YzQ1Njk1Y2EwZTg2OTEtMmRiZC00YTQ1LWJl
NTctMTI1MWUwMTk0ZWQyNDE0NDAwYjgtYTYxOS00NDY5LTllYTctNjc1YzE3YWJhZTk1MTQ2MDQz
NDItOTAyOC00ZWI0LThlOTYtZWU5YzcwNWQyYzVhMTQxMWRjYTMtY2MwNi00MzU0LTg0MTgtNGQ1
MDkwYjdiMzg2ZTY0OWU5MmUtZmNkYS00YWEwLTg0MjQtYThiOTQxNDQ2YzhhNTVhYWExZjItNjU2
Mi00YmM4LTk2ZGYtMDE4YmY5ZDZhMjkwMzM3MWUzNDMtMmQ3MS00MDczLWI0Y2UtMTQxODE0MGU5
YjdmYTVlODUxYzItN2NmOS00N2UyLWIyODQtMThlMWVkYTY4M2Q1YjE3YTMyYmItZjllMS00MTFk
LWJiM2UtM2JhYzUxYzI5OWI4

Java

  1. 予防保全・状態ベース保全のマスターガイド:実践的PM開発ステップ
  2. 角パイプベンダー完全ガイド:種類・構造・選び方のポイント
  3. コールドプレス機(冷間プレス)完全ガイド:効率的金属成形の基礎と応用
  4. 遊星ギアボックス徹底解説:コンパクトで高トルクな減速機の仕組みと用途
  5. ジェットミルドリル完全ガイド:フライス盤とボール盤を融合した多機能マシン
  6. サーボプレス機徹底解説:仕組み・メリット・機械プレスとの違い
  7. 空気圧シリンダー完全ガイド:クリーンで高速・信頼性の高いアクチュエーター
  8. ギアデコイラー徹底解説:メリット・機能・操作と選定ポイント
  9. サプライチェーンリスクを保険で守る:CBIと専門保険で財務的影響を最小化
  10. CNCフライス加工エッセンシャル:プロオペレーターのためのクイックリファレンスガイド
  11. Java Vectorの理解:使い方、特徴、ArrayListとの比較