Java - 配列のコピーと比較
Java Silver試験対策
前提
配列をclone()
メソッドで複製すると、新しいインスタンスが生成される。
String[] origin = new String[] {"1", "2"}; String[] reprica = origin.clone(); System.out.println("origin == reprica: " + (origin == reprica)); // 出力結果 // origin == reprica: false
参照型(Object)の場合は注意が必要
複製した配列が異なるインスタンスであることは上記で説明した通り。
ただ、その配列に含まれているオブジェクトは同一である。
String[] origin = new String[] {"1", "2"}; String[] reprica = origin.clone(); System.out.println("origin[0] == reprica[0]: " + (origin[0] == reprica[0])); // 出力結果 // origin[0] == reprica[0]: true
ここで、配列の要素がStringと違い、変更可能なオブジェクトであった場合を考える。
String[][] origin = new String[][] {{"1", "2"}, {"3", "4"}}; String[][] reprica = origin.clone(); System.out.println("origin[0] == reprica[0]: " + (origin[0] == reprica[0])); reprica[0][0] = "10"; System.out.println("reprica[0][0]: " + reprica[0][0]); System.out.println("origin[0][0]: " + origin[0][0]); // 出力結果 // origin[0] == reprica[0]: true // reprica[0][0]: 10 // origin[0][0]: 10
このように、複製した配列内の配列は同一オブジェクトの為、reprica
の配列を操作するとorigin
に影響するので注意が必要である。
java 配列の宣言とか初期化とか
java silver 試験対策の整理
宣言
型か変数名のいずれかに[]
をつけることで配列を表すことができる。
多次元配列の場合は次元の数だけ[]
を増やせばいい。
また次元数は型と変数名の合計であり、arr5は二次元配列になるので要注意。
// 一次元配列 int[] arr1; int arr2[]; // 二次元配列 int[][] arr3; int arr4[][]; int[] arr5[];
サイズの指定
配列を宣言しただけでは要素数が指定されておらず、値を代入することができない。
new
を使用して要素数を指定することで、値を代入することが可能になる。
// 一次元配列 int[] arr; arr = new int[2]; arr[0] = 5; // 二次元配列 int[][] arr2; arr2 = new int[2][3]; arr2[0][0] = 10;
POINT: 二次元配列のサイズ指定時は、二次元目の[3]
は[]
として指定しないことも可能。
宣言と同時に初期化を行う
宣言と同時に初期化を行う方法には以下の3通りがある。
// 上記で説明した2つを同時に行うパターン int[] arr1 = new int[2]; // 無名配列を代入するパターン int[] arr2 = new int[] {1, 2}; // 初期化子を使用するパターン int[] arr3 = {1, 2{};
POINT: 無名配列では[]
内にサイズは指定しない。
POINT: 無名配列の[]
の数は次元数と対応させる。ex) int[][] arr = new int[][] {{1, 2}, {3, 4}};
POINT: 初期化子は宣言時にのみ使用可能。代入などでは使用できない。
javanal#3 - DBコンテナの作成(postgreSQL)
概要
dockerでDBコンテナを起動して、コマンドラインから接続してみる。
手順
docker-compose.ymlの編集
db: image: postgres environment: POSTGRES_USER: ${POSTGRES_USER:-postgres} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-postgres} PGDATA: /data/postgres volumes: - postgres:/data/postgres ports: - "5432:5432" restart: unless-stopped # docker領域内にpostgresという名前のボリュームを確保 # dbコンテナを削除してもデータが消えない volumes: postgres:
DBコンテナ起動確認
コンテナの起動。docker-compose.ymlが置いてあるディレクトリで次のコマンドを実行する。
$ docker compose up -d
次のコマンドで、dbコンテナに移動する
docker exec -it xxx bash
xxxはコンテナ名。 psコマンドで確認することができる。
docker ps
DB接続確認
dbコンテナにアクセスできれば次のコマンドでdbに接続する
$ psql -d [DB名] -U [user名]
dbにアクセスできれば、docker上で問題なくdbコンテナが起動していることがわかる。
javanal#2 - webコントローラの作成
javanal#1 - javaでtwitter風webアプリを作る(環境構築) - Beginner's Hack
概要
依存関係に追加したSpring Webの機能を使用して、"http://localhost:8080/home"にアクセスするとHello Worldが表示されるようにする。
手順
コントローラの作成
// spring bootにコントローラであると認識させる @Controller // リクエストURLが"/xxx"であればこのコントローラ内のメソッドにルーティングされる @RequestMapping("/") public class HomeController { // リクエストURLが"/home"かつ、リクエストタイプが"GET"であればこのメソッドが実行される @GetMapping("home") public String home() { // 表示するhtml名を表す // この場合templatesフォルダ内のhome.htmlを表示する return "home"; } }
ビューの作成
<!doctype html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Javanal</title> </head> <body> <p>Hello World</p> </body> </html>
動作確認
javanal#1 - javaでtwitter風webアプリを作る(環境構築)
背景
spring securityやORMなど、業務で使用するライブラリ、フレームワークの練習台としてtwitter風のwebアプリを作ってみようと思いました。
java + journalでjavanalなんて名前をつけて、ゆっくりやっていきます。
とりあえず今日は環境構築をやっていきます。
環境構築
ホストPCに色々インストールするのは嫌だったので、Dockerコンテナ上で開発をしていきます。
Docker + VS Code Remote-Container docker image: openjdk:17.0.2-jdk-slim-bullseye java: 17.0.2 フレームワーク: spring boot 2.7.3
プロジェクト作成
Spring Initializrを使用してspring bootプロジェクトを作成します。
画面右上の「ADD DEPENDENCIES...」ボタンから好きな依存関係を追加できます。
とりあえずURLにアクセスして画面を表示させたかっただけなので、lombokとwebを追加しました。
設定ができたら画面中央下部の「GENERATE」でプロジェクトをダウンロードします。
プロジェクトのzipファイルがダウンロードが完了すれば、任意のフォルダに解凍します。
今後は、この解凍したプロジェクトを含むディレクトリをルートディレクトリとして進めていきます。
Docker環境構築
作成したプロジェクトの実行環境を構築していきます。
ルートディレクトリ直下にdockerフォルダを作成し、その配下に下記のようにフォルダとファイルを作成します。
. ├── README.md ├── docker │ ├── app │ │ └── Dockerfile │ └── docker-compose.yml └── javanal
docker-compose.yml
services: app: build: context: .. dockerfile: ./docker/app/Dockerfile # tty: true、もしくはフォアグラウンドで実行しているプロセスがあればコンテナが停止しない tty: true # source(ホストマシン)のディレクトリをtarget(コンテナ)にマウントする volumes: - type: bind source: ../javanal target: /app ports: - target: 8080 published: ${WEB_PORT:-8080} protocol: tcp mode: host #コンテナ内のワーキングディレクトリ working_dir: /app
Dockerfile
FROM openjdk:17.0.2-jdk-slim-bullseye
Docker動作確認
上記の手順でdocker-compose.ymlとDockerfileを作成した後、ymlファイルが存在するディレクトリで下記コマンドを実行します。
$ docker compose up -d
以下のようなメッセージが出れば成功です。
[+] Running 1/1 ⠿ Container docker_app_1 Started 3.7s
VS Code Remote-Containerの環境設定
javaの開発は、上記コンテナ内のソースコードを編集・デバッグしながら開発を行なっていきますが、Dockerコンテナを起動しただけでは、コンテナ内のソースコードを編集することができません。
そこで、VS Codeの拡張機能であるRemote-Containerを使用することによって、VSCode上でコンテナ内のソースコードを編集できるようにします。
拡張機能のインストール
VSCodeの画面でcmd + shift + xのショートカットを押して、拡張機能ページを表示させます。 検索エリアに「remote」と入力すると、下記のRemote Developmentがヒットするのでインストールします。
devcontainer.jsonの作成
下記のように.decontainerフォルダ, devcontainer.jsonを作成します。
├── .devcontainer │ └── devcontainer.json ├── README.md ├── docker │ ├── app │ │ └── Dockerfile │ └── docker-compose.yml └── javanal
devcontainer.json
{ // 任意の名前 "name": "remote-java", // DockerComposeFileを指定 "dockerComposeFile": "../docker/docker-compose.yml", // DockerComposeFileにあるservice名を指定 "service": "app", // コンテナに入ったときの作業ディレクトリ "workspaceFolder": "/app", "settings": { // bashでターミナルを起動 "terminal.integrated.defaultProfile.linux": "bash" }, // コンテナ内で使いたい拡張機能 "extensions": [ // Java関連の拡張機能パック "vscjava.vscode-java-pack", // Spring Boot関連の拡張機能パック "pivotal.vscode-boot-dev-pack", "gabrielbb.vscode-lombok" ] }
Remote - Container動作確認
ルートディレクトリでcmd + shift + P を押してコマンドパレットを開く。
「Remote-Containers: Reopen in Container」と入力し、実行する。
画面左下の表示が次の通りになれば起動完了。
これで環境構築は終了
MavenプロジェクトでMybatis generatorを使用する
手順
DBにテーブルを作成
- DBにアクセス
- CEATE TABLE
- 今回はDockerコンテナを使用するため、下記の手順で行なった。
DockerのDBコンテナに入ってクエリを実行する - Beginner's Hack
Mybatis generatorの導入
- pom.xmlにpluginを追加。
<project ...> ... <build> ... <plugins> ... <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.4.1</version> </plugin> <!-- DBにアクセスするためのドライバ --> <!-- pom.xmlに記述しない場合は後述のgeneratorConfig.xmlに記載する --> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency> </dependencies> ... </plugins> ... </build> ... </project>
generatorConfig.xmlの作成
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" > <generatorConfiguration > <!-- pom.xmlにドライバーの依存関係を追加しているため、classPathEntryの記述は不要 --> <!-- <classPathEntry location="C:\Program Files\MySQL\Connector.J 5.1\mysql-connector-java-5.1.33-bin.jar"/> --> <context id="context1" targetRuntime="MyBatis3Simple"> <!-- コメント生成の抑制 --> <commentGenerator> <property name="suppressAllComments" value="true" /> </commentGenerator> <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://mysql/sample_schema" userId="dev_usr" password="dev_usr_pass"> </jdbcConnection> <javaModelGenerator targetPackage="com.example.demo.MBGEntity" targetProject="src/main/java"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <sqlMapGenerator targetPackage="com.example.demo.MBGSql" targetProject="src/main/java"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.demo.MBGMapper" targetProject="src/main/java"> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <table schema="sample_schema" tableName="account"> </table> </context> </generatorConfiguration>
Mybatis generatorの実行
- Mavenビルドから実行
DockerのDBコンテナに入ってクエリを実行する
手順
コンテナ起動
docker-compose.ymlが配置してあるディレクトリにて
$ docker compose up -d
DBに接続
MySQLの場合
$ mysql -u root -p Enter password: <-コンソールには表示されないがパスワードを入力してEnter
データベース(スキーマ)作成
mysql> CREATE DATABASE [DB名];
テーブル作成
mysql> CREATE TABLE sample_mybatis.account( -> account_id int PRIMARY KEY AUTO_INCREMENT -> ,name varchar(30) -> );
テーブル確認
mysql> DESC sample_mybatis.account;