20200320のJavaに関する記事は16件です。

GradleでJDKをダウンロードしてJREを作る

Javaのスタンドアロンアプリケーション配布をする場合、JREを同梱しておくと環境設定が要らなくなるのですが、そのためには各プラットフォーム向けのJREをアプリケーションに同梱する必要があります。
フルサイズのJREを同梱してもいいのですが、Java9以降はモジュールがサポートされているので、せっかくなら必要な分だけを入れたJREを作る方が望ましいわけですが、その場合には各プラットフォーム向けのJDKに入っているjmods以下のファイルが必要になります。

セットアップのために手動でJDKをダウンロードするのは意外と手間なので、build.gradleに以下のようなスクリプトを追加してみました。

plugins {
  id "de.undercouch.download" version "4.0.4"
}

task prepareJDK{
  downloadAndExtractJDK("jdk/win",'http://download.bell-sw.com/java/11.0.6+10/bellsoft-jdk11.0.6+10-windows-amd64-full.zip')
  downloadAndExtractJDK("jdk/mac",'http://download.bell-sw.com/java/11.0.6+10/bellsoft-jdk11.0.6+10-macos-amd64-full.zip')
}
void downloadAndExtractJDK(jdkDir,url){
  def zipFile = "${jdkDir}/jdk.zip"
  if(file(zipFile).exists()==false){
    download {
      src url
      dest zipFile
    }
  }
  if(file("${jdkDir}/LICENSE").exists()==false){
    copy{
      from( zipTree(zipFile) ){
        include "**"  
        eachFile { fcd ->
          fcd.relativePath = new RelativePath(true, fcd.relativePath.segments.drop(1))  
        }
        includeEmptyDirs = false  
      }
      into jdkDir      
    }
  }
}
task buildJRE(type: Exec,dependsOn:prepareJDK) {
  commandLine './buildJRE.sh'
}

これを

gradle buildJRE

とすると、JDKがダウンロードされて、各プラットフォーム用のJREがbin/jreに生成されます。

prepareJDKのタスクで、Win/MacのLiberica JDK11をダウンロードして展開します。
タスク自体は単純なものですが、zip展開の際にRelativePathを使って、1階層ファイルパスを引きあげています。
普通にJDKのzipを展開すると、"jdk/win/jdk-11.0.6"という形でJDKのバージョンが入ったフォルダが作られてしまうのですが、JREを作る際にバージョンが入るとちょっと使いにくいかったため、フォルダ内のファイルを1階層引きあげています。

またJREを生成するシェル(buildJRE.sh)は、jlinkを呼び出すシェルになっています。

#!/usr/bin/env sh
MODULES="java.base,java.desktop,javafx.controls"
for PLATFORM in win mac
do
  OUTPUT_DIR=build/jre/$PLATFORM
  JMODS_DIR=jdk/$PLATFORM/jmods
  if [ -d $OUTPUT_DIR ]; then
    echo "JRE for $PLATFORM exits in $OUTPUT_DIR"
  else
    echo "creating JRE for $PLATFORM in $OUTPUT_DIR"
    jlink --compress=2 --module-path $JMODS_DIR --add-modules $MODULES --output $OUTPUT_DIR 
  fi    
done

MODULESのところに、利用するモジュールをならべて書いておきます。Librica JDKはJavaFX同梱なので、JavaFXアプリには大変便利です。

開発が本格的にOpenJDKに移行し、各種JDKがダウンロードでき、必要な分のモジュールだけが作れるようになったのは大変喜ばしいことですね。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

JAVA学习

hello world

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

IBM Cloud Object Storage(ICOS)に付属しているAsperaにSDK(Java版)を用いてファイルアップロードする

IBM Cloud Object Storage(ICOS)にファイルをアップロードする方法です。
今回はICOSに付属しているAsperaに対して、Java版のSDKを用いて操作を行います。

使用した環境

  • macOS Mojave 10.14.6
  • IntelliJ IDEA Ultimate 2019.03
  • Java8
$ java -version
java version "1.8.0_211"
Java(TM) SE Runtime Environment (build 1.8.0_211-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.211-b12, mixed mode)

Java版SDKのセットアップ

こちらを参考にセットアップ下さい。
GitHub:IBM/ibm-cos-sdk-java

基本的には pom.xml にSDKのエントリを追加するだけです。

ICOSの情報確認

IBM Cloud コンソール(Web)にログインしてICOSのサービス資格情報を確認します。
サービス資格情報はICOSに作成したバケットの資格情報の中にあります。
service_info.png

プログラム

拙作過ぎて恐縮ですが、あくまでもサンプルプログラムです。
皆さんはもっといい感じで書いてください。

IcosControl.java
package com.ibm.jp.dev;

import java.io.*;
import java.sql.Timestamp;
import java.util.List;

import com.ibm.cloud.objectstorage.ClientConfiguration;
import com.ibm.cloud.objectstorage.SDKGlobalConfiguration;
import com.ibm.cloud.objectstorage.auth.AWSCredentials;
import com.ibm.cloud.objectstorage.auth.AWSStaticCredentialsProvider;
import com.ibm.cloud.objectstorage.client.builder.AwsClientBuilder.EndpointConfiguration;
import com.ibm.cloud.objectstorage.services.s3.AmazonS3;
import com.ibm.cloud.objectstorage.services.s3.AmazonS3ClientBuilder;
import com.ibm.cloud.objectstorage.services.s3.model.*;
import com.ibm.cloud.objectstorage.oauth.BasicIBMOAuthCredentials;

public class IcosControl {
    private static String COS_ENDPOINT = "https://s3.jp-tok.cloud-object-storage.appdomain.cloud"; // eg "https://s3.us.cloud-object-storage.appdomain.cloud"
    private static String COS_API_KEY_ID = "your-api-key"; // eg "0viPHOY7LbLNa9eLftrtHPpTjoGv6hbLD1QalRXikliJ"
    private static String COS_AUTH_ENDPOINT = "https://iam.cloud.ibm.com/identity/token";
    private static String COS_SERVICE_CRN = "your-service-crn"; // eg "crn:v1:bluemix:public:cloud-object-storage:global:a/3bf0d9003abfb5d29761c3e97696b71c:d6f04d83-6c4f-4a62-a165-696756d63903::"
    private static String COS_BUCKET_LOCATION = "jp-tok"; // eg "us"
    private static String COS_BUCKET_NAME = "your-bucket-name";
    private static String COS_STORAGE_CLASS = "jp-tok-standard"; // eg us-south-standard
    private static AmazonS3 _cosClient;

    private static int SUCCESS = 0;
    private static int ERROR = -1;

    public static void main(String[] args) throws FileNotFoundException {

        SDKGlobalConfiguration.IAM_ENDPOINT = COS_AUTH_ENDPOINT;
        String bucketName = COS_BUCKET_NAME;
        String api_key = COS_API_KEY_ID;
        String service_instance_id = COS_SERVICE_CRN;
        String endpoint_url = COS_ENDPOINT;
        String location = COS_BUCKET_LOCATION;

        System.out.println("ICOS Access START: " + new Timestamp(System.currentTimeMillis()).toString());
        _cosClient = createClient(api_key, service_instance_id, endpoint_url, location);

        // Bucketのリスト
        listBuckets(_cosClient);

        System.out.println("■ putObject Start ■");

        // ファイル送信
//        File file = new File("/tmp/test-upload-java.txt");
        File file = new File(args[0]);
        FileInputStream fis = new FileInputStream(file);
        ObjectMetadata om = new ObjectMetadata();
        om.setContentLength(file.length());
        final PutObjectRequest putRequest = new PutObjectRequest(bucketName, file.getName(), fis, om);
        // アップロード
        _cosClient.putObject(putRequest);
        System.out.println("■ putObject End ■");

        System.out.println("ICOS Access END: " + new Timestamp(System.currentTimeMillis()).toString());

        // 正常終了
        System.exit(SUCCESS);

    }

    /**
     * @param api_key
     * @param service_instance_id
     * @param endpoint_url
     * @param location
     * @return AmazonS3
     */
    public static AmazonS3 createClient(String api_key, String service_instance_id, String endpoint_url, String location)
    {
        AWSCredentials credentials;
        credentials = new BasicIBMOAuthCredentials(api_key, service_instance_id);

        ClientConfiguration clientConfig = new ClientConfiguration().withRequestTimeout(5000);
        clientConfig.setUseTcpKeepAlive(true);

        AmazonS3 cos = AmazonS3ClientBuilder.standard().withCredentials(new AWSStaticCredentialsProvider(credentials))
                .withEndpointConfiguration(new EndpointConfiguration(endpoint_url, location)).withPathStyleAccessEnabled(true)
                .withClientConfiguration(clientConfig).build();
        return cos;
    }

    /**
     * @param bucketName
     * @param cosClient
     */
    public static void listObjects(String bucketName, AmazonS3 cosClient)
    {
        System.out.println();
        System.out.println("■ Listing objects in bucket " + bucketName + " ■");

        // Bucketが存在するか?
        boolean isBucket = false;
        isBucket = cosClient.doesBucketExistV2(bucketName);
        if(isBucket) {
            ObjectListing objectListing = cosClient.listObjects(new ListObjectsRequest().withBucketName(bucketName));
            for (S3ObjectSummary objectSummary : objectListing.getObjectSummaries()) {
                System.out.println(" - " + objectSummary.getKey() + "  " + "(size = " + objectSummary.getSize() + ")");
            }
        }
        System.out.println();
    }

    /**
     * @param cosClient
     */
    public static void listBuckets(AmazonS3 cosClient)
    {
        System.out.println();
        System.out.println("■ Listing buckets ■");
        final List<Bucket> bucketList = cosClient.listBuckets();
        for (final Bucket bucket : bucketList) {
            System.out.println(bucket.getName());
        }
        System.out.println();
    }

}
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.ibm.jp.dev</groupId>
    <artifactId>cos-control</artifactId>
    <version>1.0</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>com.ibm.cos</groupId>
            <artifactId>ibm-cos-java-sdk</artifactId>
            <version>2.6.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.10.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.10.0</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.2.0</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                    <archive>
                        <manifest>
                            <mainClass>com.ibm.jp.dev.IcosControl</mainClass>
                        </manifest>
                    </archive>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

アップロード実行

実行

作成したjarファイルからパラメータを与えて実行してみます。

$ java -jar target/cos-control-1.0-jar-with-dependencies.jar /tmp/test-upload-java.txt
ICOS Access START: 2020-03-20 12:03:04.983

■ Listing buckets ■
test-bucket

■ putObject Start ■
■ putObject End ■
ICOS Access END: 2020-03-20 12:03:12.164

到着確認

ちゃんと届いてました。

test-upload-java.txt              Mar 20, 2020 at 12:03:11   519 B 

あとがき

意外と、、、というと誤解を招くかもしれませんが、すんなりとアップロードは上手くいきました。
実はプログラムを作成してしばらくは、接続は出来ているのにBucketの中身を見ようとするとエラーになる、という謎事象も発生していたのですが、エンドポイントのURLに"jp-"が付いていなかったので、、、というオチでした。
皆様の参考になれば幸いです。

参考リンク

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Java sample code 02

SAMPLE GALLERYに掲載されたソースを疎通してimport文も付けました。

2.FileIO

  • テキストファイルに書き込み
  • テキストファイルに改行を入れる
  • テキストファイルの読み込み
  • ウェブページの内容の読み込み
  • ファイルを別のファイルにコピー
  • 文字コードを指定しテキストファイルを読み込む(文字化け対策)
  • テキストファイルに文字列を書き込む
  • テキストファイルの文字列を読み込む

2-1.テキストファイルに書き込み

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

public class SampleOutputStream {

    public static void main(String[] args) throws IOException {
        String text = "Hello World.";
        byte[] data = text.getBytes();
        OutputStream out = null;
        try {
            out = new FileOutputStream("OutputText.txt");//ここで書き込むファイルを指定しています。
            out.write(data);//ここで文字を書き込んでいます。
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }

    }

}

2-2.テキストファイルに改行を入れる

import java.io.*;

public class SampleOutputStream {

    private static final String NEW_LINE = "\n";//改行コードの定数

    public static void main(String[] args) throws IOException {
        String text = "Hello World.";
        byte[] data = text.getBytes();
        OutputStream out = null;
        try {
            out = new FileOutputStream("OutputText.txt");
            out.write(data);//1行目
            out.write(NEW_LINE.getBytes());//改行
            out.write(data);//2行目
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }
        //ファイルの絶対パスを取得する
        File file = new File("OutputText.txt");
        String str = file.getAbsolutePath();
        System.out.println("pass : " + str);

    }

}

2-3.テキストファイルの読み込み

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;

public class SampleInputStream {

    public static void main(String[] args) throws IOException {
        InputStream in = null;
        try {
            in = new FileInputStream("InputText.txt");
            int i = -1;

            //ファイルを読み込んでいます。
            //read()メソッドは最後まで行くと-1を返すので、-1が返ってくるまでループを回します。
            while ((i = in.read()) != -1) {
                char character = (char) i;
                System.out.print(character);//コンソールに出力
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                in.close();
            }
        }

    }

}

2-4.ウェブページの内容の読み込み

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

public class SampleInputStream {
    public static void main(String[] args) throws IOException {
        //proxy 設定
        System.setProperty("http.proxyHost","test.proxy.com");
        System.setProperty("http.proxyPort","8081");
        System.setProperty("https.proxyHost","test.proxy..com");
        System.setProperty("https.proxyPort","8081");
        System.setProperty("http.nonProxyHosts","localhost|*.nonproxy.com");
        URL url = new URL("https://www.google.co.jp/");//ウェブページを指定。
        InputStream in = null;
        try {
            in = url.openStream();
            int i = -1;
            while ((i = in.read()) != -1) {
                char character = (char) i;
                System.out.print(character);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (in != null) {
                in.close();
            }
        }

    }

}

2-5.ファイルを別のファイルにコピー

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;

public class SampleOutputStream {

    public static void main(String[] args) throws IOException {
        FileInputStream in = null;
        FileOutputStream out = null;
        FileChannel inChannel = null;
        FileChannel outChannel = null;
        try {
            in = new FileInputStream("InputText.txt");//コピー元のファイルを指定
            out = new FileOutputStream("OutputText.txt");//コピー先のファイルを指定
            inChannel = in.getChannel();
            outChannel = out.getChannel();
            inChannel.transferTo(0, inChannel.size(), outChannel);//ファイルをコピー
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (outChannel != null) {
                outChannel.close();
            }
            if (inChannel != null) {
                inChannel.close();
            }
            if (out != null) {
                out.close();
            }
            if (in != null) {
                in.close();
            }
        }

    }

}

2-6.文字コードを指定しテキストファイルを読み込む(文字化け対策)

import java.io.*;

public class SampleInputStream {

    public static void main(String[] args) throws IOException {
        InputStream in = null;
        InputStreamReader inr = null;
        try {
            in = new FileInputStream("InputText.txt");
            inr = new InputStreamReader(in, "UTF-8");//ここで文字コードを指定しています。
            int i = -1;

            while ((i = inr.read()) != -1) {
                char character = (char) i;
                System.out.print(character);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (inr != null) {
                inr.close();
            }
            if (in != null) {
                in.close();
            }
        }

    }

}

2-7.テキストファイルに文字列を書き込む

import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;

public class SampleOutputStream {

    public static void main(String[] args) throws IOException {
        FileWriter out = null;
        try {
            out = new FileWriter("OutputText.txt");
            out.write("Hello World.");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (out != null) {
                out.close();
            }
        }

    }

}

2-8.テキストファイルの文字列を読み込む

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;

public class SampleBufferedReader {

    public static void main(String[] args) throws IOException {
        FileReader fr = null;
        BufferedReader br = null;
        try {
            fr = new FileReader("InputText.txt");
            br = new BufferedReader(fr);
            String line = null;
            while ((line = br.readLine()) != null) {
                System.out.println(line);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (br != null) {
                br.close();
            }
            if (fr != null) {
                fr.close();
            }
        }

    }

}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Java sample code 01

1.Java サンプルプログラム

SAMPLE GALLERYに掲載されたソースを疎通してimport文も付けました。

  • Java 基本
    • Hello World(文字をコンソールに出力)
    • for文(ループ)
    • if文(条件分岐)
    • switch文(条件分岐)
    • 簡単な四則演算
    • メソッドの呼び出し
    • メソッドの呼び出し(引数有り)
    • 配列
    • 多次元配列
    • コンソールに入力
    • 文字数の取得
    • Listクラス
    • Mapクラス
    • Setクラス
  • Java Stringクラス(文字列)
    • 二つの文字列が同じかどうか判定:equals
    • 大文字小文字区別なく2つの文字列が同じかどうか判定:equalsIgnoreCase
    • 辞書の順序で文字列の大小を比較:compareTo
    • 大文字小文字区別なく辞書の順序で文字列の大小を比較:compareToIgnoreCase
    • 文字列の結合:concat
    • 一文字取得:charAt
    • 文字列の一部を取得:substring
    • 大文字小文字の変換:toLowerCase、toUpperCase
  • Java Mathクラス(数値処理)
    • Math.max(int, int) (大きい値を返す)
    • Math.min(int, int) (小さい値を返す)
    • Math.floor(double)(切り捨て)
    • Math.round(double) (四捨五入)
    • Math.ceil(double) (切り上げ)
    • Math.abs(int) (絶対値)
    • Math.abs(double, double) (累乗)
    • Math.random() (乱数)
  • Java Calendar、Date、DateFormatクラス(日付処理)
    • 本日(今)のCalendarオブジェクトを作成
    • 年、月、日、時、分、秒を取得
    • 特定の日付のCalendarオブジェクトを作成
    • add(int field, int amount) (Calendarオブジェクトの値を編集)
    • Calendar.before/after (日付比較)
    • java.util.Dateオブジェクトの作成
    • SimpleDateFormat(日時を任意の形式で表示)
  • Java File(ファイル処理)
    • ファイルの作成:createNewFile()
    • ファイルの削除:delete()
    • ディレクトリの作成:mkdir()
    • ディレクトリの作成:mkdirs()
    • ファイル名(またはディレクトリ名)の取得:getName()
    • 絶対パスの取得:getAbsolutePath()
    • 親ディレクトリオブジェクトを取得:getParentFile()
    • 親ディレクトリのパスを取得:getParent()
    • ディレクトリかどうか判定:isDirectory()
    • ファイルかどうか判定:isFile()
    • 隠しファイルかどうかを判定:isHidden()
    • ファイル(またはディレクトリ)か存在するかどうか判定:exists()
    • 最終更新日時を取得:lastModified()
    • ディレクトリ直下のファイルとディレクトリをすべて取得:listFiles()
    • ディレクトリ直下のファイルとディレクトリを条件を指定して取得:FilenameFilter
  • Java BigDecimalクラス(数値処理)
    • BigDecimalのオブジェクトを作成
    • 加算(足し算):add(BigDecimal augend)
    • 減算(引き算):subtract(BigDecimal subtrahend)
    • 乗算(掛け算):multiply(BigDecimal multiplicand)
    • 除算(割り算):divide(BigDecimal divisor)
    • 切り捨て:RoundingMode.FLOOR
    • 切り上げ:RoundingMode.CEILING
    • 四捨五入:RoundingMode.HALF_UP
    • 絶対値:abs()
    • 累乗:pow(int n)
    • max(BigDecimal val)
    • min(BigDecimal val)
    • 大小比較:compareTo(BigDecimal val)
    • 除算の余り:remainder(BigDecimal divisor)

1.Java サンプルプログラム

1-1.Java 基本

1-1-1.Hello World(文字をコンソールに出力)

public class SampleJava {

  public static void main(String[] args) {
    System.out.println("Hello World!");
  }

}

1-1-2.for文(ループ)

public class SampleJava {

  public static void main(String[] args) {
    int sum = 0;

    //「for (int i = 1; i <= 5; i++) {」に関して
    //int i = 1 ⇒ iを1で初期化
    //i <= 5 ⇒ iが5以下の場合ループの処理を行う
    //i++ ⇒ iに1を足す(ループないの処理が終わった後)
    for (int i = 1; i <= 5; i++) {
      sum += i;//変数sumにiを足す
    }
    System.out.println(sum);//変数sumを表示
  }

}

1-1-3.if文(条件分岐)

public class SampleJava {

  public static void main(String[] args) {
    int a = 11;//ここは自由に変える。

    if (a > 10) {//10より大きいか判定
      System.out.println("aは10より大きいです。");
    } else {
      System.out.println("aは10以下です。");
    }
  }

}

1-1-4.switch文(条件分岐)

public class SampleJava {

  public static void main(String[] args) {
    int score = 4;//ここは1~5までの数字で自由に変えます。
    String result = null;

    switch (score) {
      case 5://scoreが5の時
        result = "A";
        break;
      case 4://scoreが4の時
        result = "B";
        break;
      case 3://scoreが3の時
        result = "C";
        break;
      case 2://scoreが2の時
        result = "D";
        break;
      case 1://scoreが1の時
        result = "E";
        break;
      default://scoreが上記以外の時
        break;
    }

    if (result != null) {
      System.out.println(result + "評価です。");
    }
  }

}

1-1-5.簡単な四則演算

public class SampleJava {

  public static void main(String[] args) {
    int a = 10;
    int b = 5;

    //加算
    System.out.println(a + b);

    //減算
    System.out.println(a - b);

    //乗算
    System.out.println(a * b);

    //除算
    System.out.println(a / b);
  }

}

1-1-6.メソッドの呼び出し

public class SampleJava {

  public static void main(String[] args) {
    moring();
    noon();
    evening();
  }

  private static void moring() {
    System.out.println("朝です。");
  }

  private static void noon() {
    System.out.println("昼です。");
  }

  private static void evening() {
    System.out.println("夜です。");
  }

}

1-1-7.メソッドの呼び出し(引数有り)

public class SampleJava {

  public static void main(String[] args) {
    int output = plus(10, 30);
    System.out.println(output);
  }

  /**
   * 引数を渡せるメソッド。
   * aとbを足した結果を返します。
   * @param a
   * @param b
   * @return
   */
  private static int plus(int a, int b) {
    return a + b;
  }

}

1-1-8.配列

public class SampleJava {

  public static void main(String[] args) {
    //配列の宣言
    int[] intArray = { 10, 20, 30, 40, 50 };

    //以下の[]の中の数字を指定し、配列の中の任意の値を取り出す。この例では0~4。
    System.out.println(intArray[0]);
  }

}

1-1-9.多次元配列

public class SampleJava {

  public static void main(String[] args) {
    //多次元配列の宣言
    String[][] testScore = {
      { "国語", "80" }
      , { "算数", "90" }
      , { "社会", "70" }
      , { "理科", "75" }
    };

    System.out.println("教科:" + testScore[1][0] + "、点数:" + testScore[1][1]);
  }

}

1-1-10.コンソールに入力

import java.util.Scanner;

public class SampleJava {

    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        String inputStr = scan.next();//ここでコンソールに入力したものを取得
        System.out.println("コンソールに入力された文字は、「" + inputStr + "」です。");
    }

}

1-1-11.文字数の取得

public class SampleJava {

  public static void main(String[] args) {
    String str = "おはよう";
    System.out.println(str.length());//length()で文字数を取得
  }

}

1-1-12.Listクラス

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

public class SampleJava {

    public static void main(String[] args) {
        List<String> list = new ArrayList<String>();
        list.add("10");
        list.add("15");
        list.add("20");
        System.out.println(list.get(1));//list.get(index)でlistの値を取得します。一番最初は0
    }

}

1-1-13.Mapクラス

import java.util.HashMap;
import java.util.Map;

public class SampleJava {

    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        //以下map.put(key, value)で値をセット
        map.put("A", "100");
        map.put("B", "80");
        map.put("C", "60");
        map.put("D", "40");
        map.put("E", "20");

        //map.get(key)で指定したkeyのvalueを取得
        System.out.println(map.get("C"));
    }

}

1-1-14.Setクラス

import java.util.HashSet;
import java.util.Set;

public class SampleJava {

    public static void main(String[] args) {
        Set<String> set = new HashSet<String>();
        //以下setに値を追加。同じ値は追加されない。以下の例ではAは一つだけ追加される。
        set.add("A");
        set.add("A");
        set.add("B");
        set.add("C");

        for (String val : set) {
            System.out.println(val);
        }
    }
}

1.Java サンプルプログラム

1-2.Java Stringクラス(文字列)

1-2-1.二つの文字列が同じかどうか判定:equals

public class SampleString {

  public static void main(String[] args) {
    String str1 = "abcde";
    String str2 = "abcde";
    String str3 = "fghij";

    //「A.equals(B)」でAとBが同じ値かどうかを判定する。
    //str1とstr2は同じ値なので、true。
    System.out.println(str1.equals(str2));

    //str1とstr3は違う値なので、false。
    System.out.println(str1.equals(str3));
  }
}

1-2-2.大文字小文字区別なく2つの文字列が同じかどうか判定:equalsIgnoreCase

public class SampleString {

  public static void main(String[] args) {
    String str1 = "Abcde";
    String str2 = "abcde";
    String str3 = "fghij";

    //「A.equalsIgnoreCase(B)」で、大文字小文字を区別せずAとBが同じ値かどうかを判定する。
    //str1とstr2は同じ値なので、true(「A」と「a」は同じとみなす)。
    System.out.println(str1.equalsIgnoreCase(str2));

    //str1とstr3は違う値なので、false。
    System.out.println(str1.equalsIgnoreCase(str3));
  }
}

1-2-3.辞書の順序で文字列の大小を比較:compareTo

public class SampleString {

  public static void main(String[] args) {
    String str1 = "def";
    String str2 = "abc";
    String str3 = "ghi";
    String str4 = "def";

    //「A.compareTo(B)」で、辞書の順序で文字列の大小を比較する。
    //AがBより辞書で先にくる場合は、0以下
    //AとBが同じ場合は、0
    //AがBより辞書で後にくる場合は、0以上
    //になる。

    //str1はstr2より後にくるので0以上になる。
    System.out.println(str1.compareTo(str2));

    //str1はstr3より先にくるので0以下になる。
    System.out.println(str1.compareTo(str3));

    //str1はstr4と同じなので0になる。
    System.out.println(str1.compareTo(str4));
  }
}

1-2-4.大文字小文字区別なく辞書の順序で文字列の大小を比較:compareToIgnoreCase

public class SampleString {

  public static void main(String[] args) {
    String str1 = "def";
    String str2 = "Def";

    //「A.compareToIgnoreCase(B)」で、辞書の順序で文字列の大小を比較する。
    //大文字小文字の違いは区別しない(同じとみなす)。

    //str1はstr2と同じなので0になる(「d」と「D」は同じとみなす)。
    System.out.println(str1.compareToIgnoreCase(str2));
  }
}

1-2-5.文字列の結合:concat

public class SampleString {

  public static void main(String[] args) {
    String helloStr = "Hello";
    String spaceStr = " ";
    String worldStr = "World";

    // concat(String str)で文字列を結合
    System.out.println(helloStr.concat(spaceStr).concat(worldStr));
  }
}

1-2-6.一文字取得:charAt

public class SampleString {

  public static void main(String[] args) {
    String str = "Hello World.";

    //charAt(int index)で文字列の中の一文字を取得する。
    //取得する文字は引数のindexで指定する。
    System.out.println(str.charAt(0));
  }
}

1-2-7.文字列の一部を取得:substring

public class SampleString {

  public static void main(String[] args) {
    String str = "Hello World.";

    //substring(int beginIndex, int endIndex)で文字列の中の一部を取得する。
    //取得する文字列は引数のindexで指定する。
    System.out.println(str.substring(0, 5));
  }
}

1-2-8.大文字小文字の変換:toLowerCase、toUpperCase

public class SampleString {

  public static void main(String[] args) {
    String str1 = "HELLO";
    String str2 = "world";

    //toLowerCase()で大文字を小文字に変換する。
    System.out.println(str1.toLowerCase());

    //toUpperCaseで小文字を大文字に変換する。
    System.out.println(str2.toUpperCase());
  }
}

1.Java サンプルプログラム

1-3.Java Mathクラス(数値処理)

1-3-1.Math.max(int, int) (大きい値を返す)

public class SampleMath {

  public static void main(String[] args) {
    //以下のaとbの値は任意のものに変える
    int a = 10;
    int b = 20;

    //Math.max(int, int)は、大きいほうの引数を返します。
    System.out.println(Math.max(a, b));
  }
}

1-3-2.Math.min(int, int) (小さい値を返す)

public class SampleMath {

  public static void main(String[] args) {
    int a = 6;
    int b = 7;

    //Math.min(int, int)は、小さいほうの値を返します。
    System.out.println(Math.min(a, b));
  }
}

1-3-3.Math.floor(double)(切り捨て)

public class SampleMath {

  public static void main(String[] args) {
    double a = 100.9;

    //Math.floor(double)。小数点以下を切り捨て。
    System.out.println(Math.floor(a));
  }
}

1-3-4.Math.round(double) (四捨五入)

public class SampleMath {

  public static void main(String[] args) {
    double a = 7.5;

    //Math.round(double)。小数点以下を四捨五入。
    System.out.println(Math.round(a));
  }
}

1-3-5.Math.ceil(double) (切り上げ)

public class SampleMath {

  public static void main(String[] args) {
    double a = 20.1;

    //Math.ceil(double)。小数点以下を切り上げ。
    System.out.println(Math.ceil(a));
  }
}

1-3-6.Math.abs(int) (絶対値)

public class SampleMath {

  public static void main(String[] args) {
    int a = -7;

    //Math.abs(int)。絶対値を返す。
    System.out.println(Math.abs(a));
  }
}

1-3-7.Math.abs(double, double) (累乗)

public class SampleMath {

  public static void main(String[] args) {
    double a = 10;
    double b = 2;

    //Math.abs(double, double)。累乗を返す。この例では10の2乗で100
    System.out.println(Math.pow(a, b));
  }
}

1-3-8.Math.random() (乱数)

public class SampleMath {

  public static void main(String[] args) {
    //Math.random()。0.0以上1.0未満の数をランダムで返す。
    System.out.println(Math.random());
  }
}

1.Java サンプルプログラム

1-4.Java Calendar、Date、DateFormatクラス(日付処理)

1-4-1.本日(今)のCalendarオブジェクトを作成

import java.util.Calendar;

public class SampleCalendar {

    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
        System.out.println(cal);
    }
}

1-4-2.年、月、日、時、分、秒を取得

import java.util.Calendar;

public class SampleCalendar {

    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
        System.out.println("年:" + cal.get(Calendar.YEAR));
        System.out.println("月:" + (cal.get(Calendar.MONTH) + 1));//月は0~11のため、+1している。
        System.out.println("日:" + cal.get(Calendar.DATE));
        System.out.println("時:" + cal.get(Calendar.HOUR_OF_DAY));
        System.out.println("分:" + cal.get(Calendar.MINUTE));
        System.out.println("秒:" + cal.get(Calendar.SECOND));
    }
}

1-4-3.特定の日付のCalendarオブジェクトを作成

import java.util.Calendar;

public class SampleCalendar {

    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
        cal.set(2010, 0, 1);//2010年1月1日をセット。月は0~11なので、0をセット。

        //「2010/1/1」と表示される。
        System.out.println(cal.get(Calendar.YEAR)
                + "/" + (cal.get(Calendar.MONTH) + 1)
                + "/" + cal.get(Calendar.DATE));
    }
}

1-4-4.add(int field, int amount) (Calendarオブジェクトの値を編集)

import java.util.Calendar;

public class SampleCalendar {

    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();

        //本日の日付が表示される
        displayConsole(cal);

        //add(int field, int amount)でCalendarオブジェクトの年、月、日などの各値を増減できます。
        //以下は日を1日減らしています。
        cal.add(Calendar.DATE, -1);
        displayConsole(cal);

        //以下は月を1か月増やしています。
        cal.add(Calendar.MONTH, 1);
        displayConsole(cal);
    }

    private static void displayConsole(Calendar cal) {
        System.out.println(cal.get(Calendar.YEAR)
                + "/" + cal.get(Calendar.MONTH)
                + "/" + cal.get(Calendar.DATE));
    }
}

1-4-5.Calendar.before/after (日付比較)

import java.util.Calendar;

public class SampleCalendar {

    public static void main(String[] args) {
        Calendar calA = Calendar.getInstance();
        Calendar calB = Calendar.getInstance();
        calB.add(Calendar.DATE, 1);//calBを一日後の値にする。

        //calAがcalBより前の日時であれば、trueを返す。この例ではtrue。
        System.out.println(calA.before(calB));
        //calAがcalBより後の日時であれば、trueを返す。この例ではfalse。
        System.out.println(calA.after(calB));
    }

}

1-4-6.java.util.Dateオブジェクトの作成

import java.util.Calendar;
import java.util.Date;

public class SampleDate {

    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
        Date date = cal.getTime();
        System.out.println(date);
    }

}

1-4-7.SimpleDateFormat(日時を任意の形式で表示)

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class SampleDate {

    public static void main(String[] args) {
        Calendar cal = Calendar.getInstance();
        Date date = cal.getTime();

        //「年」を表示するフォーマットを作成。例:2016
        DateFormat format = new SimpleDateFormat("yyyy");
        System.out.println(format.format(date));

        //「月」を表示するフォーマットを作成。例:05
        format = new SimpleDateFormat("MM");
        System.out.println(format.format(date));

        //「日」を表示するフォーマットを作成。例:01
        format = new SimpleDateFormat("dd");
        System.out.println(format.format(date));

        //「時」を表示するフォーマットを作成。例:00
        format = new SimpleDateFormat("HH");
        System.out.println(format.format(date));

        //「分」を表示するフォーマットを作成。例:00
        format = new SimpleDateFormat("mm");
        System.out.println(format.format(date));

        //「秒」を表示するフォーマットを作成。例:00
        format = new SimpleDateFormat("ss");
        System.out.println(format.format(date));

        //「○○/○○/○○」を表示。例:2000/01/01
        format = new SimpleDateFormat("yyyy/MM/dd");
        System.out.println(format.format(date));

        //「○○年○○月○○日 ○○:○○:○○(○○時○○分○○秒)」を表示。例:2000年1月1日
        format = new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
        System.out.println(format.format(date));

    }

}

1.Java サンプルプログラム

1-5.Java File(ファイル処理)

1-5-1.ファイルの作成:createNewFile()

import java.io.File;
import java.io.IOException;

public class SampleDate {

    public static void main(String[] args) {
        //ファイルオブジェクトを作成しています。引数には作成するファイルのパスを指定します。
        File file = new File("C:\\sample\\test.txt");
        try {
            //以下でファイルを作成しています。
            file.createNewFile();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

}

1-5-2.ファイルの削除:delete()

import java.io.File;

public class SampleDate {

    public static void main(String[] args) {
        File file = new File("C:\\sample\\test.txt");
        //以下で指定したファイルを削除します。
        file.delete();
    }

}

1-5-3.ディレクトリの作成:mkdir()

import java.io.File;

public class SampleDate {

    public static void main(String[] args) {
        File file = new File("C:\\sample\\sampledir");
        //以下で指定したディレクトリを作成します。
        file.mkdir();
    }

}

1-5-4.ディレクトリの作成:mkdirs()

import java.io.File;

public class SampleDate {

    public static void main(String[] args) {
        File file = new File("C:\\sample\\sampledir\\sampledir2");
        //以下でディレクトリを作成します。mkdir()と異なり、親ディレクトリで必要なものも作成します。
        //この例では「C:\\sample」というディレクトリがある状態で実行した場合、
        //「sampledir」と「sampledir2」の二つが作成されます。
        file.mkdirs();
    }

}

1-5-5.ファイル名(またはディレクトリ名)の取得:getName()

import java.io.File;

public class SampleDate {

    public static void main(String[] args) {
        File file = new File("C:\\sample\\test.txt");
        //指定したファイル(またはディレクトリ)の名称を取得
        System.out.println(file.getName());
    }

}

1-5-6.絶対パスの取得:getAbsolutePath()

import java.io.File;

public class SampleDate {

    public static void main(String[] args) {
        File file = new File("C:\\sample\\test.txt");
        //ファイルの絶対パスを取得
        System.out.println(file.getAbsolutePath());
    }

}

1-5-7.親ディレクトリオブジェクトを取得:getParentFile()

import java.io.File;

public class SampleDate {

    public static void main(String[] args) {
        File file = new File("C:\\sample\\test.txt");

        //親ディレクトリオブジェクトを取得
        File parent = file.getParentFile();

        System.out.println(parent);
    }

}

1-5-8.親ディレクトリのパスを取得:getParent()

import java.io.File;

public class SampleDate {

    public static void main(String[] args) {
        File file = new File("C:\\sample\\test.txt");

        //親ディレクトリのパスを取得
        String parentPath = file.getParent();

        System.out.println(parentPath);
    }
}

1-5-9.ディレクトリかどうか判定:isDirectory()

import java.io.File;

public class SampleDate {

    public static void main(String[] args) {
        File file = new File("C:\\sample");

        //以下でディレクトリかどうかを判定する。この例ではディレクトリのため、true。
        System.out.println(file.isDirectory());
    }
}

1-5-10.ファイルかどうか判定:isFile()

import java.io.File;

public class SampleDate {

    public static void main(String[] args) {
        File file = new File("C:\\sample");

        //以下でファイルかどうかを判定する。この例ではディレクトリのため、false。
        System.out.println(file.isFile());
    }
}

1-5-11.隠しファイルかどうかを判定:isHidden()

import java.io.File;

public class SampleDate {

    public static void main(String[] args) {
        File file = new File("C:\\sample\\test.txt");

        //以下で隠しファイルかどうかを判定する。
        System.out.println(file.isHidden());
    }
}

1-5-12.ファイル(またはディレクトリ)か存在するかどうか判定:exists()

import java.io.File;

public class SampleDate {

    public static void main(String[] args) {
        File file = new File("C:\\sample\\test.txt");

        //以下でファイル(またはディレクトリ)か存在するかどうかを判定する
        System.out.println(file.exists());
    }
}

1.Java サンプルプログラム

1-6.Java BigDecimalクラス(数値処理)

1-6-1.BigDecimalのオブジェクトを作成

import java.math.BigDecimal;

public class SampleBigDecimal {

    public static void main(String[] args) {
        //以下でBigDecimalのオブジェクトを作成
        BigDecimal obj = new BigDecimal("1");

        System.out.println(obj);
    }
}

1-6-2.加算(足し算):add(BigDecimal augend)

import java.math.BigDecimal;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj1 = new BigDecimal("1");
        BigDecimal obj2 = new BigDecimal("2");

        //add(BigDecimal augend)で加算を行い、結果を返す。
        BigDecimal result = obj1.add(obj2);

        System.out.println(result);
    }
}

1-6-3.減算(引き算):subtract(BigDecimal subtrahend)

import java.math.BigDecimal;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj1 = new BigDecimal("5");
        BigDecimal obj2 = new BigDecimal("3");

        //subtract(BigDecimal subtrahend)で減算を行い、結果を返す。
        BigDecimal result = obj1.subtract(obj2);

        System.out.println(result);
    }
}

1-6-4.乗算(掛け算):multiply(BigDecimal multiplicand)

import java.math.BigDecimal;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj1 = new BigDecimal("2");
        BigDecimal obj2 = new BigDecimal("4");

        //multiply(BigDecimal multiplicand)で乗算を行い、結果を返す。
        BigDecimal result = obj1.multiply(obj2);

        System.out.println(result);
    }
}

1-6-5.除算(割り算):divide(BigDecimal divisor)

import java.math.BigDecimal;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj1 = new BigDecimal("30");
        BigDecimal obj2 = new BigDecimal("5");

        //divide(BigDecimal divisor)で除算を行い、結果を返す。
        BigDecimal result = obj1.divide(obj2);

        System.out.println(result);
    }
}

1-6-6.切り捨て:RoundingMode.FLOOR

import java.math.BigDecimal;
import java.math.RoundingMode;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj1 = new BigDecimal("400.545");

        //setScale(int newScale, RoundingMode roundingMode)で桁数と丸め動作を指定。
        //RoundingMode.FLOOR(切り捨て)
        //以下の例では、小数点第一位を切り捨てた結果のオブジェクトを返している。
        obj1 = obj1.setScale(0, RoundingMode.FLOOR);

        System.out.println(obj1);
    }
}

1-6-7.切り上げ:RoundingMode.CEILING

import java.math.BigDecimal;
import java.math.RoundingMode;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj1 = new BigDecimal("400.545");

        //setScale(int newScale, RoundingMode roundingMode)で桁数と丸め動作を指定。
        //RoundingMode.CEILING(切り上げ)
        //以下の例では、小数点第二位を切り上げた結果のオブジェクトを返している。
        obj1 = obj1.setScale(1, RoundingMode.CEILING);

        System.out.println(obj1);
    }
}

1-6-8.四捨五入:RoundingMode.HALF_UP

import java.math.BigDecimal;
import java.math.RoundingMode;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj1 = new BigDecimal("400.545");

        //setScale(int newScale, RoundingMode roundingMode)で桁数と丸め動作を指定。
        //RoundingMode.HALF_UP(四捨五入)
        //以下の例では、小数点第三位を四捨五入した結果のオブジェクトを返している。
        obj1 = obj1.setScale(2, RoundingMode.HALF_UP);

        System.out.println(obj1);
    }
}

1-6-9.絶対値:abs()

import java.math.BigDecimal;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj = new BigDecimal("-1");

        //abs()で絶対値を返す
        System.out.println(obj.abs());
    }
}

1-6-10.累乗:pow(int n)

import java.math.BigDecimal;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj = new BigDecimal("2");

        //pow(int n)で、値を累乗(n乗)した結果を返す。
        System.out.println(obj.pow(4));
    }
}

1-6-11.max(BigDecimal val)

import java.math.BigDecimal;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj1 = new BigDecimal("4");
        BigDecimal obj2 = new BigDecimal("3");

        //max(BigDecimal val)でオブジェクトを比較し、大きいほうを返す。
        System.out.println(obj1.max(obj2));
    }
}

1-6-12.min(BigDecimal val)

import java.math.BigDecimal;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj1 = new BigDecimal("4");
        BigDecimal obj2 = new BigDecimal("3");

        //min(BigDecimal val)でオブジェクトを比較し、小さいほうを返す。
        System.out.println(obj1.min(obj2));
    }
}

1-6-13.大小比較:compareTo(BigDecimal val)

import java.math.BigDecimal;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj1 = new BigDecimal("1");
        BigDecimal obj2 = new BigDecimal("3");

        //compareTo(BigDecimal val)
        //オブジェクトを引数のものと比較し、
        //大きければ「1」
        //同じならば「0」
        //小さければ「-1」
        //を返す。
        if (obj1.compareTo(obj2) > 0) {
            System.out.println("大きい");
        } else if (obj1.compareTo(obj2) < 0) {
            System.out.println("小さい");
        } else {
            System.out.println("同じ");
        }
    }
}

1-6-14.除算の余り:remainder(BigDecimal divisor)

import java.math.BigDecimal;

public class SampleBigDecimal {

    public static void main(String[] args) {

        BigDecimal obj1 = new BigDecimal("11");
        BigDecimal obj2 = new BigDecimal("3");

        //remainder(BigDecimal divisor)で除算を行い、余りを返す。
        BigDecimal result = obj1.remainder(obj2);

        System.out.println(result);
    }
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Liberica JDK 11 の JavaFX 11 (OpenJFX) で Hello World する

『みんなの Java OpenJDK から始まる大変革期!』を読んでいて、何となく Liberica JDK 11 の JavaFX 11 で Getting Started with JavaFX をやってみたのでメモっとく。

ほとんどの OpenJDK ディストリビューションには JavaFX (OpenJFX) は含まれていない。なので、Getting Started with JavaFX の手順を素直にやるとちょっと手間がかかる。でも、Liberica JDK 11 を SDKMAN! などでインストールすれば簡単に JavaFX 11 で遊べる。

SDKMAN! で Liberica JDK 11 をインストールする

SDKMAN! で Liberica JDK 11 をインストールする。JavaFX が含まれないバージョンもあるので注意する。インストールできる Java バージョンの一覧は sdk list java コマンドで確認できる。

$ sdk install java 11.0.6.fx-librca

Getting Started with JavaFX のコードで Hello World する

HelloFX.java というファイル名で下記のコードを保存する。Java と JavaFX のバージョンを取得して、それを含めた文字列で Label コントロールを生成し StackPane レイアウトに配置して表示しているようだ。

HelloFX.java
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class HelloFX extends Application {

    @Override
    public void start(Stage stage) {
        String javaVersion = System.getProperty("java.version");
        String javafxVersion = System.getProperty("javafx.version");
        Label l = new Label("Hello, JavaFX " + javafxVersion + ", running on Java " + javaVersion + ".");
        Scene scene = new Scene(new StackPane(l), 640, 480);
        stage.setScene(scene);
        stage.show();
    }

    public static void main(String[] args) {
        launch();
    }

}

それではコンパイルして、実行してみよう。SDKMAN! で Liberica JDK 11 が設定されていることを必ず確認すること。設定されていなければ sdk use java 11.0.6.fx-librca コマンドを実行してから、下記のコマンドを実行してね。

$ sdk current java
Using java version 11.0.6.fx-librca
$ javac HelloFX.java
$ java HelloFX

こんな画面が表示されたら成功。

Hello, JavaFX 11.0.6, running on Java 11.0.6.

アプリケーションとして配布するとなると考えることは多いけど、社内ツールで簡単な GUI がほしいとかそういうことであれば、Liberica JDK 11 を用いた JavaFX は便利そうだ。


今回は Liberica JDK 11 の JavaFX 11 (OpenJFX) で Hello World してみた。ちゃんとした開発環境を構築するとなると、IntelliJ IDEA と Scene Builder を利用するといいみたい。ちょっと眺めただけなのだが『The Definitive Guide to Modern Java Clients with JavaFX』にそういう開発環境の構築手順が記載されていた。

参考文献

みんなの Java OpenJDK から始まる大変革期!
The Definitive Guide to Modern Java Clients with JavaFX

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Java 14でTable Driven Testを実装する

はじめに

Java 14がついにリリースされたので、
以前書いたJavaでTable Driven Testを実装するで紹介したソースコードを、
Java 14でPreviewとして追加されたRecordsを使って書き直してみました。

Java 14以前のTable Driven Test

以前のソースコードでは、
テストケースをTestCaseという内部クラスで保持していました。
コンストラクタやgetterはLombokを使って定義していました。

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.experimental.Accessors;
import org.junit.jupiter.api.*;

import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;

class MathTest {

    @Nested
    static class Pow {

        @AllArgsConstructor
        @Getter
        @Accessors(fluent = true)
        static class TestCase {
            private String name;
            private double x;
            private double y;
            private double expected;
        }

        @TestFactory
        Stream<DynamicNode> testPow() {
            return Stream.of(
                    new TestCase("pow(2,1)", 2, 1, 2),
                    new TestCase("pow(2,2)", 2, 2, 4),
                    new TestCase("pow(2,3)", 2, 3, 8),
                    new TestCase("pow(2,0)", 2, 0, 1),
                    new TestCase("pow(2,-1)", 2, -1, 0.5),
                    new TestCase("pow(2,+Inf)", 2, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY),
                    new TestCase("pow(2,-Inf)", 2, Double.NEGATIVE_INFINITY, 0),
                    new TestCase("pow(+Inf,2)", Double.POSITIVE_INFINITY, 2, Double.POSITIVE_INFINITY),
                    new TestCase("pow(-Inf,2)", Double.NEGATIVE_INFINITY, 2, Double.POSITIVE_INFINITY)
            ).map(testCase -> DynamicTest.dynamicTest(
                    testCase.name(),
                    () -> {
                        double result = Math.pow(testCase.x(), testCase.y());
                        assertEquals(testCase.expected(), result);
                    })
            );
        }
    }

}

Java 14のTable Driven Test

今回のソースコードでは、
テストケースをrecordで保持するようにしました。
recordを使うことで、Lombokを使った場合よりもコード量を減らすことができました。

import org.junit.jupiter.api.DynamicNode;
import org.junit.jupiter.api.DynamicTest;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.TestFactory;

import java.util.stream.Stream;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class MathTest {

    @Nested
    static class Pow {

        record TestCase(String name, double x, double y, double expected) {
        }

        @TestFactory
        Stream<DynamicNode> testPow() {
            return Stream.of(
                    new TestCase("pow(2,1)", 2, 1, 2),
                    new TestCase("pow(2,2)", 2, 2, 4),
                    new TestCase("pow(2,3)", 2, 3, 8),
                    new TestCase("pow(2,0)", 2, 0, 1),
                    new TestCase("pow(2,-1)", 2, -1, 0.5),
                    new TestCase("pow(2,+Inf)", 2, Double.POSITIVE_INFINITY, Double.POSITIVE_INFINITY),
                    new TestCase("pow(2,-Inf)", 2, Double.NEGATIVE_INFINITY, 0),
                    new TestCase("pow(+Inf,2)", Double.POSITIVE_INFINITY, 2, Double.POSITIVE_INFINITY),
                    new TestCase("pow(-Inf,2)", Double.NEGATIVE_INFINITY, 2, Double.POSITIVE_INFINITY)
            ).map(testCase -> DynamicTest.dynamicTest(
                    testCase.name(),
                    () -> {
                        double result = Math.pow(testCase.x(), testCase.y());
                        assertEquals(testCase.expected(), result);
                    })
            );
        }
    }

}

まとめ

これからも新機能を使ってソースコードを改善していけると良いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

結城浩『Java言語で学ぶデザインパターン入門』(SB Creative)読んでみた

こんにちは、ふぎとです。

今回は結城浩さんの本で、デザインパターンを学んでみ
ました。

「デザインパターン」とは

この本を手に取ったきっかけは、情報系の友人からの薦
めがあったからでした。「実務で絶対に役に立つから」
という太鼓判を鵜呑みに、おっかなびっくり手にとった
次第です。

まず浮かんだのは、「デザインパターンってなに?」と
いうこと。これは本書冒頭に説明がありました。

"プログラミングを行っていると、以前と同じことを繰
 り返しているなあ、と気づくときがあります。経験が
 増すにつれ、そのような「パターン」(….)を次の開発
 に当てはめていくことができるようになります。 
 Erich Gamma, Richard Helm, Ralph Johnson, John
 Vlissidesの4人が、そのような開発者の「経験」や
 「内的な蓄積」としてのパターンを
 
 「デザインパターン」

 という形に整理しました。”(「はじめに」より)

要するに、デザインパターンとは「先人の知恵」のよう
なもの。また、開発者同士の「共通言語」のようなもの、
だということです。因みに、考案した4人はthe Gang of
Four(GoF)と呼ばれているらしいです。つよそう。

本書の章立て

本書はそのGoFが定めた23個のデザインパターンをひとつ
ずつ、Javaプログラムで実例を示しながら紹介していま
す。章立ては以下の通り。

 1. Iterator 1つ1つ数え上げる
 2. Adapter 一皮かぶせて再利用
 3. Template Method 具体的な処理をサブクラスにまかせる
 4. Factory Method インスタンス生成をサブクラスにまかせる
 5. Singleton たった1つのインスタンス
 6. Prototype コピーしてインスタンスを作る
 7. Builder 複雑なインスタンスを組み立てる
 8. Abstract Factory 関連する部品を組み合わせて製品を作る
 9. Bridge 機能の階層と実装の階層を分ける
 10.Strategy アルゴリズムをごっそり切り替える
 11.Composite 容器と中身の同一視
 12.Decorator 飾り枠と中身の同一視
 13.Visitor 構造を渡り歩きながら仕事をする
 14.Chain of Responsibility 責任のたらい回し
 15.Facade シンプルな窓口
 16.Mediator 相手は相談役1人だけ
 17.Observer 状態の変化を通知する
 18.Memento 状態を保存する
 19.State 状態をクラスとして表現する
 20.Flyweight 同じものを共有して無駄をなくす
 21.Proxy 必要になってから作る
 22.Command 命令をクラスにする
 23.Interpreter 文法規則をクラスで表現する

自分が取り組んだこと

・サンプルとして掲載されたプログラムを自分で書き写
 し、実行した
 →→23のデザインパターンそれぞれについて、期待通り
  に動かすことができた
・どのクラスがどんな役割をになっているのか、解説を
 読んで理解に努めた

今後やりたいこと

・やり残した、章末の練習問題を解き切る
・Javaのプログラムが動く仕組みについて勉強する

最後にひとこと

もし僕の記事に対しての補足や、「今後やりたいこと」
に対するオススメ本などありましたら、ぜひコメントで
いただけると嬉しいです!

では今日はこの辺で。ふぎとでした。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Javaにおけるmainメソッドとは

はじめに

java初心者による、情報の整理としての記事です。
修正点・記載すべき追加情報などありましたらご指摘いただけると幸いです。

mainメソッドとは

public static void main(String[]args){
\\statement
}

・多くの場合この形で定義されるメソッド(例外パターンは記事後半に記載)
statement(文)の中には、
  1.変数実行の文
  2.計算式の文
  3.命令実行の文
など様々な文を記述する。それぞれの文は上から順に処理されていく。

・Javaプログラムの起点となるメソッド(エントリーポイント)
Javaのプログラムを起動した際に一番最初に参照されるポイントです。mainメソッドが起点となるため、他のクラスで定義したメソッドなどはmainメソッド内で呼びださない限り実行されることはありません。

また、mainメソッドが存在しない場合、このようなエラーが発生します。
Exception in thread "main" java.lang.NoSuchMethodError: main

mainメソッドを分解する

public修飾子

public修飾子は全てのクラスからのアクセスを許可する修飾子です。
mainメソッドにおいては、Javaプログラムの起点となるメソッドであり、様々なクラスからのアクセスを想定してpublic修飾子をつけることが必要です。

static

staticキーワードがつけられたフィールドやメソッドの総称を静的メンバと呼称します。
その中でもstaticキーワードがついたメソッドは静的メソッド(クラスメソッド)と呼称されます。つまり、mainメソッドは静的メソッドであるということが言えます。

静的メソッドは以下の三つの特徴を持ちます。
1.メソッド自体がクラスに属するようになる
2.インスタンスにメソッドの分身がセットされる
3.インスタンスを生み出さなくとも呼び出せる

ここで、重要なのは3の特徴です。
mainメソッドはJavaプログラムの起点となるメソッドなので、起動時点では、Java仮想空間には1つもインスタンスが生成されていない状態が考えられます。
この状態に対処するために、mainメソッドはstaticキーワードをつける必要があるということになります。

補足的内容になりますが、他のクラス内に記述され、一旦オブジェクトを生成してから記述されたメソッドはプログラムの起動時に呼びだされる必要性がないため、staticキーワードをつける必要がないということになります。

void

このメソッドが戻り値を返さないことを示しています。

main

メソッド名。JVMが参照する識別子。

String[]args

ここでのルールとしては、String型の配列、またはString型の可変長引数を指定する必要があるというものです。(理由が探しきれなかったので、保留します)
なので、引数に当たるargsの部分は変更可能ということになります。
しかし、一般的にはargsが使用される例が多いようです。

mainメソッドの使用上の注意点

ここまでの記述で、mainメソッドは特殊なメソッドであるということが分かりました。
ここで、実際に使用する上で注意したいパターンを一つ挙げておきます。

public class Cleric {

String name = "ユウダイ";
int hp = 50;
final int maxHp = 50;
int mp = 30;
final int maxMp = 30;

public static void main(String[] args) {
            // TODO 自動生成されたメソッド・スタブ
            Cleric cleric = new Cleric();
            cleric.selfAid();
            cleric.pray(3);
}

public void selfAid() {
    System.out.println(this.name + "は『自己回復』を唱えた!");
    this.mp -= 5;
    this.hp = this.maxHp;
    System.out.println("HPが最大まで回復した!");
}

このように一つのクラスの中に、mainメソッドとselfAidメソッドが同居しているパターンです。
ここではmainメソッドはClericクラス内に記述されていますが、実際にmainメソッドはあらゆるクラスの起点となるメソッドなので。Clericクラスとは関係がありません。(語弊がある気がしますが)なので、混乱を避けるためにも、mainメソッドを実行するクラスとして独立したクラス(例えばMainクラス)を生成して、mainメソッドを実行するクラスを分けたほうが理解がしやすいということがあるかと思います。

いろいろなmainメソッドの書き方

public static void main(String args[]) { }
public static void main(String...args) { }
public strictfp static void main(String[]args) { }
public static void main(final String[]args) { }
final static synchronized strictfp void main(final String[]args) { }

ありがとうございました。以上。

【参考文献】
・『スッキリわかるJava入門 第3版』
【参考URL】
・【Java入門】mainメソッドとその引数(args)、戻り値について解説
 https://www.sejuku.net/blog/65082
・Javaのmain()メソッドの説明
 https://www.codeflow.site/ja/article/java-main-method
・mainメソッドとクラスの関係
 https://www.javadrive.jp/start/about/index4.html
・最初に呼び出されるクラスのメソッド
 https://www.javadrive.jp/start/const/index3.html
・【しっかり押さえたい】Javaのmainメソッドとは?と使い方
 https://eng-entrance.com/java-basic-main

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Oracle Code One 2019で興味深かったセッション

2010/1/18(土) にOracle Code One 2019 報告会 in 大阪で「オッス! Oracle Code One」というタイトルで登壇させて頂きました。

そこで興味深かったセッションとして「Duke’s Star Trek with Java 12 Code Challenges」というセッションの内容を紹介いたしました。
図1.png

Oracle Code Oneは朝から晩まで4日間に渡るカンファレンスなのでいくつものセッションを聞くのですが、セッションの数が多すぎていつもセッション選びに苦労します。
しかしStar Trekの好きな私はタイトルを見ただけでほぼノータイムで予約を入れました。
内容はJDK6からJDK12までの各バージョンで取り入れられた新機能について4択のクイズ形式で紹介するというもので、アニメーションで楽しいスライドを使って進められとてもいいセッションでした。

報告会ではこのセッションで出たクイズの一部(と補足のために私が作ったオリジナル)を紹介しました。

例えばJDK7についての紹介では

public class ShipDoorEp1 implements AutoCloseable {

  public void open() { throw new RuntimeException("Fail to open door."); }

  @Override
  public void close() throws Exception {
    System.out.println("Ship door is closed."); 
  }

  public static void main(String... doorMalfunction) {
    try (ShipDoorEp1 shipDoor = new ShipDoorEp1()) {
      shipDoor.open();
    } catch (Exception e) {
      System.out.println(e.getMessage());
    } finally {
      System.out.println("The end.");
    }
  }
}

このようなコードを実行したら以下のA, B, C, D のどれになるかというものです。
正解は報告会で使用した資料(記事の最後のリンク)を見てください。

A)
Fail to open door.
The end.
Ship door is closed.

B)
Fail to open door.
Ship door is closed.
The end.

C)
Ship door is closed.
Fail to open door.
The end.

D)
Fail to open door.
The end.

この問題はかなり簡単だと思いますが、セッションではさらに深く掘り下げて

public class ShipDoorEp2 implements AutoCloseable {

  public void open() { throw new RuntimeException("Fail to open door."); }

  @Override
  public void close() throws Exception { 
    throw new RuntimeException("Fail to auto-close door."); 
  }

  public static void main(String... doorMalfunction) {
    try (ShipDoorEp2 shipDoor = new ShipDoorEp2()) {
      shipDoor.open();
    } catch (Exception e) {
      System.out.println(e.getMessage());
      System.out.println(e.getSuppressed()[0].getMessage());
    } finally {
      System.out.println("The end.");
    }
  }
}

このようなsuppressed exceptions(抑制済み例外)についても触れていました。
(問題の選択肢、解答は資料でご確認ください)

もちろんこのセッション以外にも興味深かったセッションはたくさんあったのですが、色々機能追加などがあったJDK6からJDK12までのバージョンアップの歴史を振り返ることができたという点でこのセッションが一番印象に残りました。

来年もOracle Code Oneに参加していいセッションが聴ければいいなあと思います。

発表に使った資料です

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

onConfigurationChangedで回転時のレイアウトを変更

やりたかったこと

ImageViewの画像を画面いっぱい(アスペクト比はそのまま)に表示してかつ、ボタンを真下に置きたかったのですが、、、
図1.png
横回転するとボタンが隠れてしまうし、横画面に合わせてレイアウト変えると縦回転したときにボタンの位置がずれてしまってました。
レイアウト用のxmlは1つだけにしたかったので、ソース内で動的にImageViewのサイズを変えることにしました。

やったこと

レイアウト

  • レイアウトはConstraintLayoutを使う
  • ImageViewの設定:
    • サイズ(縦向き時):
      • height: wrap_content
      • width: 0dp(match constraint)
    • サイズ(横向き時):
      • height: 0dp(match constraint)
      • width: wrap_content
    • 描画の縦横比を維持するためにandroid:adjustViewBounds = trueを指定
    • ボタンをくっつけるためにapp:layout_constraintVertical_chainStyle="packed"を指定

Activity

  • マニフェストで、Activityにandroid:configChanges="orientation|screenSize"を追加。縦横の回転を検出できるようにする。
  • 縦横の向きが変わるとonConfigurationChangedがコールされる。その中で、ImageViewのレイアウトを更新。

ソース

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:adjustViewBounds="true"
        android:padding="8dp"
        app:layout_constraintBottom_toTopOf="@+id/button"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.0"
        app:layout_constraintVertical_chainStyle="packed"
        app:srcCompat="@drawable/ic_launcher_background" />

    <Button
        android:id="@+id/button"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="8dp"
        android:text="Button"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/imageView" />

</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
public class MainActivity extends AppCompatActivity {
    ImageView imageView;
    Button button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //UI取得
        imageView = findViewById(R.id.imageView);
        button = findViewById(R.id.button);
        //一応、起動時の向き取得
        int orientation = getResources().getConfiguration().orientation;
        UpdateLayout(orientation); //レイアウト更新
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        int orientation = newConfig.orientation; //向き取得
        UpdateLayout(orientation); //レイアウト更新
    }

    /**
     * レイアウト更新
     * @param orientation 向き
     */
    protected void UpdateLayout(int orientation){
        //ImageViewのLayoutParam取得
        LayoutParams param = imageView.getLayoutParams();
        if (orientation == Configuration.ORIENTATION_PORTRAIT) {
            // 縦向きの場合
            Log.d("UpdateLayout", "縦向き");
            param.height = LayoutParams.WRAP_CONTENT;
            param.width = 0;
        }
        else if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
            // 横向きの場合
            Log.d("UpdateLayout", "横向き");
            param.height = 0;
            param.width = LayoutParams.WRAP_CONTENT;
        }
        imageView.setLayoutParams(param);
    }
}

参考記事

Androidで横向きか縦向きかを判定する
Androidで画像の縦横比を保ったまま画面幅いっぱいに表示する
https://techblog.zozo.com/entry/constraint_layout

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

新卒2年目がSilver/Goldに2ヵ月で合格した話

導入

こんにちは。けちょんです。
Java Silver/Goldに合格したので、嬉しくて記事を書きました。
これから受験する方の参考になれば、と思います。

受験結果

Java Silver

得点:88/100
image.png

Java Gold

得点:91/100
image.png

勉強開始時点の知識

業務でエンハンスは行っていたため、基本的なデータ構造や文法は分かる
ジェネリクス?ラムダ式?ストリーム??何それな状態

勉強時間

Java Silver

勉強時間:約8時間
基礎知識は既に築かれていたため、演習問題2つとその復習に力を注いだ
また、Goldの勉強をしていれば割とカバーされる

Java Gold

勉強時間:約70時間
ゼロベースから、広く深く知識を習得する必要があったため、時間を要した
特にラムダ式などは新しい概念となるため、習得に時間を要した

スケジュール

1/24 勉強開始
2/8 Gold黒本の練習問題を読了
2/16 Gold白本の練習問題を読了
2/19 Silver白本の演習問題で8割獲得
3/1 Silver黒本の演習問題で9割獲得
3/4 Gold黒本の演習問題(巻末)で7.5割獲得
3/11 Silver合格
3/12 Gold白本の演習問題で8割獲得
3/16 Gold黒本の演習問題(ダウンロード版)で6.5割獲得
3/18 Gold合格

教材

GoldとSilverでそれぞれJava8の黒本と白本を利用
Goldの黒本/白本についての所感は以下
(Silverはあまり覚えてないため省略します、、、)

黒本

練習問題:とても簡単
演習問題(巻末):普通
演習問題(ダウンロード版):とても難しい

練習問題

ジェネリクス?ラムダ式?ストリーム??な人はまず黒本の練習問題を解くのががおすすめです。
一週目は問題よりも解説を読み込み基礎知識を得ながら、とにかく手を動かします。
手を動かすことで、知識が拡張されますし、記憶に定着されます。
また、初めて得た知識はすぐにアウトプットするのがおすすめです。
※Qiitaで記事にした内容は今でもよく覚えてます

演習問題

白本の練習問題を解いた後に解くのがおすすめです。
個人的には試験と同じ環境(途中で調べてはいけない等)にする必要はないと思います。
なぜなら、答え合わせして、復習している頃には多くの疑問を忘れてしまうからです。
細かいことにこだわらず、より成長できる選択肢を選びましょう。
全ての疑問は発生した都度潰しましょう。
ちなみに演習問題(ダウンロード版)は解く必要がありません
知識がマニアックで、実際の試験ではほとんど出題されませんでした。
可変リダクション操作が大好きな人は解くといいと思います。

白本

練習問題:普通
演習問題(巻末):少し難しい

練習問題

黒本の練習問題を解き終えたら、白本の練習問題を解きましょう。
基礎知識をもちろん、出題範囲に幅広さがあります。
黒本より難易度が上がるため、黒本で自信がついてきた人はがっかりすると思います。
ここでも、とにかくコードを書くことが近道です。

演習問題

ある程度実力がついてきたと思う方は、試験と同じ環境で解いてみましょう。
ここで合格点に届かない場合はコーディングが足りていないと思います。
不正解が多い分野を分析し、コードを書きましょう。

それぞれ受験してみた感想

Java Silver

業務で専門的にJavaを扱っているのであれば、合格できるレベルは必須だと思います。
もちろん通常業務で使用しない知識も多いですが、以下のような必須知識も多いです。
・「値渡し」と「参照渡し」の違い(正確にはJavaに参照渡しは存在しないようですが)
・StringとStringBuilderの違い
などなど

Java Gold

業務で詳細設計も行っているのであれば、あった方が役立つと思うくらいです。必須ではありません。
純粋に知識量が増えることで、以下メリットがあると思います。
・最適なクラスやそのメソッドを選択できる
 例)Dateクラスではなく、Date And Time API
   ArrayListとLinkedListの最適な選択
   などなど
ラムダ式やストリームの問題が多数出題されますが、業務で安易に使用するのは可読性を損なう危険があり、避けるべきです。

まとめ

色々書きましたが、知識量が格段に増えたので、取得して良かったと思います。
これからの時代、Javaはこれまでほど利用されなくなっていくかもしれません。
しかし、静的型付け言語を一つマスターするというのは非常に重要な礎となるはずです。
是非皆さんも受験してみてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

新卒2年目がJava Silver/Goldに2ヵ月で合格した話

導入

こんにちは。けちょんです。
Java Silver/Goldに合格したので、嬉しくて記事を書きました。
これから受験する方の参考になれば、と思います。

受験結果

Java Silver

得点:88/100
image.png

Java Gold

得点:91/100
image.png

勉強開始時点の知識

業務でエンハンスは行っていたため、基本的なデータ構造や文法は分かる
ジェネリクス?ラムダ式?ストリーム??何それな状態

勉強時間

Java Silver

勉強時間:約8時間
基礎知識は既に築かれていたため、演習問題2つとその復習に力を注いだ
また、Goldの勉強をしていれば割とカバーされる

Java Gold

勉強時間:約70時間
ゼロベースから、広く深く知識を習得する必要があったため、時間を要した
特にラムダ式などは新しい概念となるため、習得に時間を要した

スケジュール

1/24 勉強開始
2/8 Gold黒本の練習問題を読了
2/16 Gold白本の練習問題を読了
2/19 Silver白本の演習問題で8割獲得
3/1 Silver黒本の演習問題で9割獲得
3/4 Gold黒本の演習問題(巻末)で7.5割獲得
3/11 Silver合格
3/12 Gold白本の演習問題で8割獲得
3/16 Gold黒本の演習問題(ダウンロード版)で6.5割獲得
3/18 Gold合格

教材

GoldとSilverでそれぞれJava8の黒本と白本を利用
Goldの黒本/白本についての所感は以下
(Silverはあまり覚えてないため省略します。。。)

黒本

練習問題:とても簡単
演習問題(巻末):普通
演習問題(ダウンロード版):とても難しい

練習問題

ジェネリクス?ラムダ式?ストリーム??な人はまず黒本の練習問題を解くのががおすすめです。
一週目は問題よりも解説を読み込み基礎知識を得ながら、とにかく手を動かします。
手を動かすことで、知識が拡張されますし、記憶に定着されます。
また、初めて得た知識はすぐにアウトプットするのがおすすめです。
※Qiitaで記事にした内容は今でもよく覚えてます

演習問題

白本の練習問題を解いた後に解くのがおすすめです。
個人的には試験と同じ環境(途中で調べてはいけない等)にする必要はないと思います。
なぜなら、答え合わせして、復習している頃には多くの疑問を忘れてしまうからです。
細かいことにこだわらず、より成長できる選択肢を選びましょう。
全ての疑問は発生した都度潰しましょう。
ちなみに演習問題(ダウンロード版)は解く必要がありません
知識がマニアックで、実際の試験ではほとんど出題されませんでした。
可変リダクション操作が大好きな人は解くといいと思います。

白本

練習問題:普通
演習問題(巻末):少し難しい

練習問題

黒本の練習問題を解き終えたら、白本の練習問題を解きましょう。
基礎知識をもちろん、出題範囲に幅広さがあります。
黒本より難易度が上がるため、黒本で自信がついてきた人はがっかりすると思います。
ここでも、とにかくコードを書くことが近道です。

演習問題

ある程度実力がついてきたと思う方は、試験と同じ環境で解いてみましょう。
ここで合格点に届かない場合はコーディングが足りていないと思います。
不正解が多い分野を分析し、コードを書きましょう。

それぞれ受験してみた感想

Java Silver

業務で専門的にJavaを扱っているのであれば、合格できるレベルは必須だと思います。
もちろん通常業務で使用しない知識も多いですが、以下のような必須知識も多いです。
・「値渡し」と「参照渡し」の違い(正確にはJavaに参照渡しは存在しないようですが)
・StringとStringBuilderの違い
などなど

Java Gold

業務で詳細設計も行っているのであれば、あった方が役立つと思うくらいです。必須ではありません。
純粋に知識量が増えることで、以下メリットがあると思います。
・最適なクラスやそのメソッドを選択できる
 例)Dateクラスではなく、Date And Time API
   ArrayListとLinkedListの最適な選択
   などなど
ラムダ式やストリームの問題が多数出題されますが、業務で安易に使用するのは可読性を損なう危険があり、避けるべきです。

まとめ

色々書きましたが、知識量が格段に増えたので、取得して良かったと思います。
これからの時代、Javaはこれまでほど利用されなくなっていくかもしれません。
しかし、静的型付け言語を一つマスターするというのは非常に重要な礎となるはずです。
是非皆さんも受験してみてください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CentOS7にEclipse GlassFish 5.1.0をインストールする方法

CentOS7にEclipse GlassFish 5.1.0をインストールする手順を紹介します。

1. 環境

  • CentOS Linux release 7.7.1908
root@CENTOS7 ~]# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
[root@CENTOS7 ~]#
  • jdk-8u241(jdk-8u241-linux-x64.rpm)(jdk14では動作しませんでした。)
インストール
[root@CENTOS7 ~]# rpm -ivh jdk-8u241-linux-x64.rpm
警告: jdk-8u241-linux-x64.rpm: ヘッダー V3 RSA/SHA256 Signature、鍵 ID ec551f03: NOKEY
準備しています...              ################################# [100%]
更新中 / インストール中...
   1:jdk1.8-2000:1.8.0_241-fcs        ################################# [100%]
Unpacking JAR files...
        tools.jar...
        plugin.jar...
        javaws.jar...
        deploy.jar...
        rt.jar...
        jsse.jar...
        charsets.jar...
        localedata.jar...
[root@CENTOS7 ~]#

2. Eclipse GlassFish 5.1.0のダウンロード

以下のコマンドでglassfish-5.1.0.zipをダウンロードします。(もしくはダウンロードサイトからダウンロードします。)

curl -OL http://mirror.kakao.com/eclipse/glassfish/glassfish-5.1.0.zip

実行結果
[root@CENTOS7 ~]# curl -OL http://mirror.kakao.com/eclipse/glassfish/glassfish-5.1.0.zip
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  111M  100  111M    0     0   292k      0  0:06:31  0:06:31 --:--:--  302k
[root@CENTOS7 ~]#

以下のコマンドでダウンロードしたファイルのハッシュ値がダウンロードサイトの値と同じであることを確認します。

sha512sum glassfish-5.1.0.zip

実行結果
[root@CENTOS7 ~]# sha512sum glassfish-5.1.0.zip
10d99061319178d65e8f8604f41caaca2ea561cbdc426d0fdf6163ead549e9c63c154c6ff648133a5b37bec14940a48b7c893544fa19f900a8c62273e445ed14  glassfish-5.1.0.zip
[root@CENTOS7 ~]#

01.png

02.png

3. glassfish-5.1.0.zipを解凍

以下のコマンドでglassfish-5.1.0.zip/opt配下に解凍します。

unzip -d /opt glassfish-5.1.0.zip

実行結果
[root@CENTOS7 ~]# unzip -d /opt glassfish-5.1.0.zip
Archive:  glassfish-5.1.0.zip
   creating: /opt/glassfish5/
   creating: /opt/glassfish5/glassfish/
   creating: /opt/glassfish5/glassfish/domains/
   creating: /opt/glassfish5/glassfish/domains/domain1/
   creating: /opt/glassfish5/glassfish/domains/domain1/config/
  inflating: /opt/glassfish5/glassfish/domains/domain1/config/admin-keyfile

~~~ 省略 ~~~

  inflating: /opt/glassfish5/mq/lib/props/broker/default.properties
  inflating: /opt/glassfish5/mq/lib/props/broker/install.properties
  inflating: /opt/glassfish5/mq/lib/tyrus-standalone-client.jar
[root@CENTOS7 ~]# cd /opt
[root@CENTOS7 opt]# ls -l
合計 0
drwxr-xr-x. 7 root root 92  1月 28  2019 glassfish5
[root@CENTOS7 opt]#

4. glassfishユーザーの作成

以下のコマンドで「glassfish」ユーザーを作成します。(パスワードも「glassfish」)

useradd -p $(perl -e 'print crypt("glassfish", "\$6\$salt03")') glassfish

実行結果
[root@CENTOS7 opt]# useradd -p $(perl -e 'print crypt("glassfish", "\$6\$salt03")') glassfish
[root@CENTOS7 opt]#

5. のオーナー及びグループを変更

以下のコマンドでglassfish5ディレクトリのオーナー及びグループをglassfishに変更します。

chown -R glassfish:glassfish glassfish5

実行結果
[root@CENTOS7 opt]# chown -R glassfish:glassfish glassfish5
[root@CENTOS7 opt]# ls -l
合計 0
drwxr-xr-x. 7 glassfish glassfish 92  1月 28  2019 glassfish5
[root@CENTOS7 opt]#

6. asenv.confの修正

/opt/glassfish5/glassfish/config/asenv.confの最後の行に
AS_JAVA="/usr/java/jdk1.8.0_241-amd64"
を追加します。

asenv.conf
#
# Copyright (c) 2004, 2018 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0, which is available at
# http://www.eclipse.org/legal/epl-2.0.
#
# This Source Code may also be made available under the following Secondary
# Licenses when the conditions for such availability set forth in the
# Eclipse Public License v. 2.0 are satisfied: GNU General Public License,
# version 2 with the GNU Classpath Exception, which is available at
# https://www.gnu.org/software/classpath/license.html.
#
# SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
#

#
#                       * * *    N O T E     * * *
#
# Although the lines in this file are formatted as environment
# variable assignments, this file is NOT typically invoked as a script
# from another script to define these variables.  Rather, this file is read
# and processed by a server as it starts up.  That scanning code resolves
# the relative paths against the GlassFish installation directory.
#
# Yet, this file is also where users of earlier versions have sometimes added
# a definition of AS_JAVA to control which version of Java GlassFish
# should use.  As a result, in order to run a user-specified version of Java,
# the asadmin and appclient scripts do indeed invoke this file as a
# script - but ONLY to define AS_JAVA.  Any calling script should not
# rely on the other settings because the relative paths will be resolved
# against the current directory when the calling script is run, not the
# installation directory of GlassFish, and such resolution will not work
# correctly unless the script happens to be run from the GlassFish installation
# directory.
#

AS_IMQ_LIB="../../mq/lib"
AS_IMQ_BIN="../../mq/bin"
AS_CONFIG="../config"
AS_INSTALL=".."
AS_DEF_DOMAINS_PATH="../domains"
AS_DEF_NODES_PATH="../nodes"
AS_DERBY_INSTALL="../../javadb"
AS_JAVA="/usr/java/jdk1.8.0_241-amd64"

7. ファイアウォールの設定

/usr/lib/firewalld/services配下に以下のglassfish.xmlを作成します。

glassfish.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>glassfish</short>
  <description>GlassFish Server</description>
  <port protocol="tcp" port="4848"/>
  <port protocol="tcp" port="8080"/>
  <port protocol="tcp" port="8181"/>
</service>

以下のコマンドでglassfish.xmlで設定したポートを通すようにファイアウォールを設定します。

firewall-cmd --permanent --add-service=glassfish

実行結果
[root@CENTOS7 services]# firewall-cmd --permanent --add-service=glassfish
success
[root@CENTOS7 services]#

以下のコマンドでfirewalldを再起動します。

systemctl restart firewalld.service

実行結果
[root@CENTOS7 services]# systemctl restart firewalld.service
[root@CENTOS7 services]#

以下のコマンドでservicesにglassfishが追加されていることを確認します。

firewall-cmd --list-all

実行結果
[root@CENTOS7 services]# firewall-cmd --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp0s3
  sources:
  services: dhcpv6-client glassfish http ssh
  ports: 8888/tcp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

[root@CENTOS7 services]#

8. glassfish起動

以下のコマンドでglassfishユーザーにスイッチします。

su - glassfish

実行結果
[root@CENTOS7 services]# su - glassfish
最終ログイン: 2020/03/19 (木) 23:39:44 JST日時 pts/0
[glassfish@CENTOS7 ~]$

glassfishの起動、停止、再起動コマンドは以下となります。

起動:/opt/glassfish5/glassfish/bin/asadmin start-domain
停止:/opt/glassfish5/glassfish/bin/asadmin stop-domain
再起動:/opt/glassfish5/glassfish/bin/asadmin restart-domain

glassfishを起動します。

実行結果
[glassfish@CENTOS7 ~]$ /opt/glassfish5/glassfish/bin/asadmin start-domain
Waiting for domain1 to start .......
Successfully started the domain : domain1
domain  Location: /opt/glassfish5/glassfish/domains/domain1
Log File: /opt/glassfish5/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.
[glassfish@CENTOS7 ~]$

9. 接続確認

以下のURLでブラウザから接続します。

http://<サーバのIPアドレス>:8080/

以下の画面が開くと接続OKです。

03.png

10. 管理画面の設定

以下のURLでブラウザから管理画面に接続します。

http://<サーバのIPアドレス>:4848/

04.png

エラーが表示される場合、以下を設定します。

管理ユーザーのパスワードを設定します。

/opt/glassfish5/glassfish/bin/asadmin change-admin-password

実行結果
[glassfish@CENTOS7 ~]$ /opt/glassfish5/glassfish/bin/asadmin change-admin-password
Enter admin user name [default: admin]>(そのまま)
Enter the admin password>(そのまま)
Enter the new admin password>admin
Enter the new admin password again>admin
Command change-admin-password executed successfully.
[glassfish@CENTOS7 ~]$

以下のコマンドでenable-secure-adminを有効にします。

/opt/glassfish5/glassfish/bin/asadmin --host localhost --port 4848 enable-secure-admin

実行結果
[glassfish@CENTOS7 ~]$ /opt/glassfish5/glassfish/bin/asadmin --host localhost --port 4848 enable-secure-admin
Enter admin user name>  admin
Enter admin password for user "admin">
You must restart all running servers for the change in secure admin to take effect.
Command enable-secure-admin executed successfully.
[glassfish@CENTOS7 ~]$

glassfishを再起動します。

/opt/glassfish5/glassfish/bin/asadmin restart-domain

実行結果
[glassfish@CENTOS7 ~]$ /opt/glassfish5/glassfish/bin/asadmin restart-domain
Successfully restarted the domain
Command restart-domain executed successfully.
[glassfish@CENTOS7 ~]$

再度以下のURLでブラウザから管理画面に接続します。

http://<サーバのIPアドレス>:4848/

05.png

設定した管理ユーザー/パスワード(admin/admin)でログインします。

06.png

管理画面にログインできました。

11. systemdのserviceファイル作成

/usr/lib/systemd/system配下に以下のglassfish.serviceを作成します。

/usr/lib/systemd/system/glassfish.service
[Unit]
Description=GlassFish Server v5.1
After=syslog.target network.target remote-fs.target

[Service]
Type=oneshot
RemainAfterExit=yes
PIDFile=/var/run/glassfish.pid
ExecStart=/opt/glassfish5/glassfish/bin/asadmin start-domain
ExecStop=/opt/glassfish5/glassfish/bin/asadmin stop-domain
ExecReload=/opt/glassfish5/glassfish/bin/asadmin restart-domain
TimeoutStartSec=300
TimeoutStopSec=30
User=glassfish
Group=glassfish

[Install]
WantedBy=multi-user.target

systemctlコマンドでの起動、停止、再起動は以下となります。

起動:systemctl start glassfish
停止:systemctl stop glassfish
再起動:systemctl restart glassfish

参考

Eclipse GlassFish | projects.eclipse.org

エラー情報

今回はjavaとしてjdk-8u241をインストールして実行しました。

しかし、jdk14では以下のエラーが発生し実行できませんでした。

実行結果
[glassfish@CENTOS7 ~]$ /opt/glassfish5/glassfish/bin/asadmin start-domain
Exception in thread "main" java.lang.NullPointerException
        at com.sun.enterprise.module.common_impl.AbstractModulesRegistryImpl.initializeServiceLocator(AbstractModulesRegistryImpl.java:128)
        at com.sun.enterprise.module.common_impl.AbstractModulesRegistryImpl.newServiceLocator(AbstractModulesRegistryImpl.java:120)
        at com.sun.enterprise.module.common_impl.AbstractModulesRegistryImpl.createServiceLocator(AbstractModulesRegistryImpl.java:194)
        at com.sun.enterprise.module.common_impl.AbstractModulesRegistryImpl.createServiceLocator(AbstractModulesRegistryImpl.java:200)
        at com.sun.enterprise.module.single.StaticModulesRegistry.createServiceLocator(StaticModulesRegistry.java:64)
        at com.sun.enterprise.admin.cli.CLIContainer.getServiceLocator(CLIContainer.java:193)
        at com.sun.enterprise.admin.cli.CLIContainer.getLocalCommand(CLIContainer.java:231)
        at com.sun.enterprise.admin.cli.CLICommand.getCommand(CLICommand.java:207)
        at com.sun.enterprise.admin.cli.AdminMain.executeCommand(AdminMain.java:347)
        at com.sun.enterprise.admin.cli.AdminMain.doMain(AdminMain.java:282)
        at org.glassfish.admin.cli.AsadminMain.main(AsadminMain.java:33)
[glassfish@CENTOS7 ~]$

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【プログラミング言語】使い手 呼び名リスト

プログラミング言語の使い手の呼び名を集めれるだけ集めました。使われてるかよくよくわからないものも含まれているので、使う際はあくまで自己責任でオナシャス( ˘ω˘ )スヤァ…

※アルファベット順

C

  • C-man(シーマン)

C Sharp

  • C#er(シーシャーパー)

C++

  • C++er(シープラプラー)

COBOL

  • COBOLer(コボラー)

Flash

  • Flasher(フラッシャー)

GO

  • Gopher(ゴーファー)

Haskell

  • Haskeller(ハスケラー)

JAVA

  • JAVAer(ジャバー)
  • Java屋
  • Javaヤー

JavaScript

  • JavaScripter(ジャバスクリプター)
  • JSer(ジェイサー)

Julia

  • Juliana(ジュリアナ)

Kotlin

  • Kotliner(コトリナー)

node

  • noder(ノーダー)

LISP

  • LISPer(リスパー)

Objective-C

  • Objective-C-man(オブジェクトシーマン)

Perl

  • Perler(パーラー)
  • Perl Monger(パール・モンガー)

PHP

  • PHPer(ペチパー)

Python

  • Pythonista(パイソニスタ)
  • Pythonian(パイソニアン)
  • Pythonist(パイソニスト)
  • Pythoner(パイソナー)

Ruby

  • Rubyist(ルビイスト)

Rails

  • Railser(レイルザー)

Salesforce/APEX

  • Trailblazer(トレイルブレイザー)

Scala

  • Scalalian(スカラリアン)
  • Scalman(スカルマン)

Swift

  • Swift屋
  • Swiftヤー

TypeScript

  • TypeScripter(タイプスクリプター)

Unity

  • Unityist(ユニティスト)

.NET

  • .NETer(ドットネット)

以上!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【鉄板ネタ】プログラミング言語の使い手 呼び名リスト

プログラミング言語の使い手の呼び名を集めれるだけ集めました。使われてるかよくよくわからないものも含まれているので、使う際はあくまで自己責任でオナシャス( ˘ω˘ )スヤァ…

※アルファベット順

C

  • C-man(シーマン)

C Sharp

  • C#er(シーシャーパー)

C++

  • C++er(シープラプラー)

COBOL

  • COBOLer(コボラー)

Flash

  • Flasher(フラッシャー)

GO

  • Gopher(ゴーファー)

Haskell

  • Haskeller(ハスケラー)

JAVA

  • JAVAer(ジャバー)
  • Java屋
  • Javaヤー

JavaScript

  • JavaScripter(ジャバスクリプター)
  • JSer(ジェイサー)

Julia

  • Juliana(ジュリアナ)

Kotlin

  • Kotliner(コトリナー)

node

  • noder(ノーダー)

LISP

  • LISPer(リスパー)

Objective-C

  • Objective-C-man(オブジェクトシーマン)

Perl

  • Perler(パーラー)
  • Perl Monger(パール・モンガー)

PHP

  • PHPer(ペチパー)

Python

  • Pythonista(パイソニスタ)
  • Pythonian(パイソニアン)
  • Pythonist(パイソニスト)
  • Pythoner(パイソナー)

Ruby

  • Rubyist(ルビイスト)

Rails

  • Railser(レイルザー)

Salesforce/APEX

  • Trailblazer(トレイルブレイザー)

Scala

  • Scalalian(スカラリアン)
  • Scalman(スカルマン)

Swift

  • Swift屋
  • Swiftヤー

TypeScript

  • TypeScripter(タイプスクリプター)

Unity

  • Unityist(ユニティスト)

.NET

  • .NETer(ドットネット)

以上!!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む