メモ > 技術 > プログラミング言語: Java > 基本の文法
■基本の文法
■値と計算
package org.example;
public class Main {
public static void main(String[] args) {
// 四則計算
System.out.println(5 + 2); // 7
System.out.println(5 - 2); // 3
System.out.println(5 * 2); // 10
System.out.println(5 / 2); // 2
System.out.println(5 % 2); // 1
// 計算の優先順位
System.out.println(2 + 3 * 4); // 14
System.out.println((2 + 3) * 4); // 20
// 計算に実数を使用すると結果も実数になる
System.out.println(5.0 / 2); // 2
// 文字列の表示
System.out.println("Hello world!");
// 文字列のフォーマット
System.out.println("%sは%,d円です。".formatted("書籍", 1200));
}
}
■変数と型
package org.example;
public class Main {
public static void main(String[] args) {
// 変数(varによる型推論)
var a1 = "TEST1";
var a2 = 'A';
var a3 = 500;
var a4 = 2.5;
System.out.println("a1 = " + a1 + ", a2 = " + a2 + ", a3 = " + a3 + ", a4 = " + a4);
// 変数(型指定)
String b1 = "TEST2"; // String型は文字列を扱うクラス
char b2 = 'B';
int b3 = 600;
double b4 = 3.2;
System.out.println("b1 = " + b1 + ", b2 = " + b2 + ", b3 = " + b3 + ", b4 = " + b4);
// 型変換
int c1 = Integer.parseInt("1234");
double c2 = Double.parseDouble("5.6");
int c3 = (int)b4;
double c4 = (double)b3;
System.out.println("c1 = " + c1 + ", c2 = " + c2 + ", c3 = " + c3 + ", c4 = " + c4);
// 変数(ラッパークラスでの型指定)
String d1 = "TEST2"; // String型は文字列を扱うクラス
Character d2 = 'B';
Integer d3 = 600;
Double d4 = 3.2;
System.out.println("d1 = " + d1 + ", d2 = " + d2 + ", d3 = " + d3 + ", d4 = " + d4);
}
}
定数にする場合、宣言時に「final」キーワードを付与する
また文法上のルールでは無いが、定数名はすべて大文字のアンダースコア形式にしておくといい
// 定数の宣言
final int INT = 1234;
final char CHAR = 'C';
final boolean BOOL = true;
final String MESSAGE = "こんにちは。";
System.out.println(INT);
System.out.println(CHAR);
System.out.println(BOOL);
System.out.println(MESSAGE);
■標準API
package org.example;
import java.time.*;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// 現在の日付
System.out.println(LocalDate.now());
//System.out.println(java.time.LocalDate.now());
// 現在の時間
System.out.println(LocalTime.now());
//System.out.println(java.time.LocalTime.now());
// 現在の日時
System.out.println(LocalDateTime.now());
//System.out.println(java.time.LocalDateTime.now());
// 日時の操作
var date = LocalDate.of(2022, 12, 28);
System.out.println(date);
var time = LocalTime.of(17, 30);
System.out.println(time);
var datetime = LocalDateTime.of(date, time);
System.out.println(datetime);
// 日時のフォーマット1
System.out.printf("%tY年%<tm月%<td日%n", datetime);
//System.out.println("%tY年%<tm月%<td日".formatted(datetime));
// 日時のフォーマット2
var formatter = DateTimeFormatter.ofPattern("yyyy年M月d日");
System.out.println(formatter.format(date));
}
}
■SwingによるGUI
package org.example;
import javax.swing.*;
public class Main {
public static void main(String[] args) {
// ウインドウを定義
var frame = new JFrame("テスト");
frame.setSize(600, 400);
frame.setLocation(200, 200);
frame.setVisible(true);
// ラベルを定義
JLabel label = new JLabel("ハロー!");
frame.add(label);
// パネルを定義
JPanel panel = new JPanel();
panel.add(label);
frame.add(panel);
/*
// ラベルを定義
JLabel label = new JLabel("ハロー!");
label.setBounds(10, 10, 100, 20);
// パネルを定義
JPanel panel = new JPanel();
panel.setLayout(null);
panel.add(label);
frame.add(panel);
*/
}
}
■条件分岐
package org.example;
public class Main {
public static void main(String[] args) {
// 条件分岐
var str = "test";
if (str.equals("test")) {
System.out.println("等しい");
} else {
System.out.println("等しくない");
}
// switch(Java14から導入された書き方)
var num = 2;
switch (num) {
case 1 -> System.out.println("数字は1");
case 2, 3 -> System.out.println("数字は2もしくは3");
default -> System.out.println("その他の数字");
}
// switch(Java14より前の書き方)
switch (num) {
case 1:
System.out.println("数字は1");
break;
case 2:
case 3:
System.out.println("数字は2もしくは3");
break;
default:
System.out.println("その他の数字");
break;
}
}
}
■配列
package org.example;
public class Main {
public static void main(String[] args) {
// 配列
var oddNumbers = new int[5];
oddNumbers[0] = 1;
oddNumbers[1] = 3;
oddNumbers[2] = 5;
oddNumbers[3] = 7;
oddNumbers[4] = 10;
System.out.println(oddNumbers[1]); // 3
System.out.println(oddNumbers.length); // 5
// 配列(初期化と同時に値を設定)
var evenNumbers = new int[]{2, 4, 6, 8, 10, 12};
System.out.println(evenNumbers[1]); // 4
System.out.println(evenNumbers.length); // 6
// 型のラッパークラスでも宣言できる
//var evenNumbers = new Integer[]{2, 4, 6, 8, 10, 12};
// 変数に型を指定すると、初期化時の宣言を簡略ができる
//int[] evenNumbers = {2, 4, 6, 8, 10, 12};
//Integer[] evenNumbers = {2, 4, 6, 8, 10, 12};
// 文字列クラスの配列
var names = new String[]{"山田", "佐藤", "鈴木"};
System.out.println(names[0]); // 山田
System.out.println(names.length); // 3
// 多次元配列
var numbers = new int[][]{{1, 2, 3}, {4, 5, 6}};
System.out.println(numbers[0][0]); // 1
System.out.println(numbers.length); // 2
}
}
■リスト
package org.example;
import java.util.*;
public class Main {
public static void main(String[] args) {
// 変更できないリスト
var names1 = List.of("山田", "佐藤", "鈴木");
System.out.println(names1.get(0)); // 山田
System.out.println(names1.size()); // 3
// 変更できるリスト(型はジェネリクスで指定)
var names2 = new ArrayList<String>();
names2.add("山田");
names2.add("佐藤");
names2.add("鈴木");
System.out.println(names2.get(1)); // 佐藤
System.out.println(names2.size()); // 3
// 変更できるリストの初期値を指定(型はジェネリクスで指定)
List<String> names3 = new ArrayList<String>(names1);
System.out.println(names3.get(2)); // 鈴木
System.out.println(names3.size()); // 3
// 変更できるリストの初期値を指定&ジェネリクスの型推論
var names4 = new ArrayList<>(names1);
System.out.println(names4.get(2)); // 鈴木
System.out.println(names4.size()); // 3
// 基本型のラッパークラス(ジェネリクスには参照型を指定する必要があるため、int, double, boolean, charではなくInteger, Double, Boolean, Characterとして扱う)
List<Integer> numbers = new ArrayList<Integer>(List.of(2, 4, 6));
System.out.println(numbers.get(1)); // 4
System.out.println(numbers.size()); // 3
}
}
■マップ
package org.example;
import java.util.*;
public class Main {
public static void main(String[] args) {
// 変更できないマップ
var fruits1 = Map.of("apple", "リンゴ", "orange", "ミカン", "grape", "ブドウ");
System.out.println(fruits1.get("orange")); // ミカン
System.out.println(fruits1.size()); // 3
// 変更できるマップ(型はジェネリクスで指定)
var fruits2 = new HashMap<String, String>();
fruits2.put("apple", "リンゴ");
fruits2.put("orange", "ミカン");
fruits2.put("grape", "ブドウ");
System.out.println(fruits2.get("orange")); // ミカン
System.out.println(fruits2.size()); // 3
}
}
■繰り返し
package org.example;
public class Main {
public static void main(String[] args) {
// forによる繰り返し
for (int i = 0; i < 5; i++) {
System.out.println(i);
}
// whileによる繰り返し
int j = 0;
while (j < 5) {
System.out.println(j);
j++;
}
// Listを定義
var fruits = List.of("Apple", "Orange", "Grape");
// 基本for文でListを処理
for (int i = 0; i < fruits.size(); i++) {
System.out.println(fruits.get(i));
}
// 拡張for文でListを処理
for (var fruit: fruits) {
System.out.println(fruit);
}
}
}
■Stream
以下はループで処理したもの
package org.example;
import java.util.*;
public class Main {
public static void main(String[] args) {
var names = List.of("Yamamoto", "Sato", "Suzuki");
// 5文字以上の名前を抽出(ループで処理)
var result = new ArrayList<String>();
for (var name: names) {
if (name.length() >= 5) {
result.add(name);
}
}
System.out.println(result);
// 5文字以上の名前をカウント(ループで処理)
var count = 0;
for (var name: names) {
if (name.length() >= 5) {
count++;
}
}
System.out.println(count);
}
}
以下はStreamで処理したもの(結果は同じ)
package org.example;
import java.util.*;
import java.util.stream.Collectors;
public class Main {
public static void main(String[] args) {
var names = List.of("Yamamoto", "Sato", "Suzuki");
// 5文字以上の名前を抽出(Streamで処理)
var result = names.stream()
.filter(s -> s.length() >= 5)
.collect(Collectors.toCollection(ArrayList::new));
System.out.println(result);
// 5文字以上の名前をカウント(ループで処理)
var count = names.stream()
.filter(s -> s.length() >= 5)
.count();
System.out.println(count);
}
}
以下のような処理ができる
package org.example;
import java.util.*;
import java.util.stream.*;
public class Main {
public static void main(String[] args) {
var names = List.of("Yamamoto", "Sato", "Suzuki");
// 配列をそのまま返す
var result1 = names.stream()
.toList();
System.out.println(result1); // [Yamamoto, Sato, Suzuki]
// 個数を数える
var result2 = names.stream()
.count();
System.out.println(result2); // 3
// すべての要素が「Y」を含むか確認
var result3 = names.stream()
.allMatch(s -> s.contains("Y"));
System.out.println(result3); // false
// いずれか1つの要素が「Y」を含むか確認
var result4 = names.stream()
.anyMatch(s -> s.contains("Y"));
System.out.println(result4); // true
// すべての要素が「X」を含まないか確認
var result5 = names.stream()
.noneMatch(s -> s.contains("X"));
System.out.println(result5); // true
// 要素を1つずつ出力
names.stream()
.forEach(s -> System.out.println(s));
// 中間処理が不要なら、Streamを介さずに処理できる
names.forEach(s -> System.out.println(s));
// 要素を1つずつ出力
names.stream()
.limit(2) // 処理する要素は2つまで
.sorted() // ソート
.distinct() // 重複があれば省く
.forEach(s -> System.out.println(s));
var integers = new int[]{2, 4, 6, 8, 10};
var doubles = new double[]{2.0, 4.0, 6.0, 8.0, 10.0};
// 明示的に整数を扱う
var result6 = IntStream.of(integers).sum();
System.out.println(result6); // 30
// 明示的に少数を扱う
var result7 = DoubleStream.of(doubles).sum();
System.out.println(result7); // 30.0
}
}
Optionalで値の有無を管理できる
package org.example;
import java.util.*;
public class Main {
public static void main(String[] args) {
var names = List.of("Yamamoto", "Sato", "Suzuki");
// オプショナル(値があるとき)
var result1 = names.stream()
.filter(s -> s.length() >= 3)
.findAny();
System.out.println(result1); // Optional[Yamamoto]
// オプショナル(値がないとき)
var result2 = names.stream()
.filter(s -> s.length() >= 10)
.findAny();
System.out.println(result2); // Optional.empty
// オプショナルに値があるかどうかを判定
if (result1.isPresent()) {
System.out.println("result1に値があります"); // こちらが出力される
} else {
System.out.println("result1に値がありません");
}
if (result2.isEmpty()) {
System.out.println("result2に値がありません"); // こちらが出力される
} else {
System.out.println("result2に値があります");
}
}
}
■正規表現
package org.example;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
Pattern pattern = Pattern.compile("0\\d+-\\d+-\\d+");
if (pattern.matcher("090-1234-5678").find()) {
System.out.println("電話番号です。");
} else {
System.out.println("電話番号ではありません。");
}
if (pattern.matcher("12345").find()) {
System.out.println("電話番号です。");
} else {
System.out.println("電話番号ではありません。");
}
}
}
■メソッド
staticとして宣言すると、「クラス名.メソッド名()」でメソッドを呼び出すことができる
さらにクラス名を省略することで、メソッドを関数のように扱うことができる
package org.example;
public class Main {
public static void main(String[] args) {
// 基本的なメソッド
message();
//Main.message();
// 引数のあるメソッド
greeting("Java");
// 戻り値のあるメソッド
System.out.println("計算結果は" + twice(3) + "です。");
}
/*
* 基本的なメソッド
*/
static void message() {
System.out.println("Hello world!");
}
/*
* 引数のあるメソッド
*/
static void greeting(String name) {
System.out.println("Hello " + name + "!");
}
/*
* 戻り値のあるメソッド
*/
static int twice(int x) {
return x * 2;
}
}
■ファイル入出力
ファイルの書き込み
package org.example;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main {
public static void main(String[] args) {
var message = """
TEST1
TEST2
TEST3
""";
try {
var p = Path.of("test.txt");
Files.writeString(p, message);
} catch (IOException e) {
System.out.println("ファイルに書き込めません: " + e.getMessage());
}
System.out.println("Complete!");
}
}
ファイルの読み込み
package org.example;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
public class Main {
public static void main(String[] args) {
try {
var p = Path.of("test.txt");
String s = Files.readString(p);
System.out.println(s);
} catch (IOException e) {
System.out.println("ファイルを読み込めません: " + e.getMessage());
}
System.out.println("Complete!");
}
}
■HTTP
クライアント
package org.example;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) {
HttpClient client = HttpClient.newHttpClient();
URI uri = URI.create("https://example.com/");
HttpRequest req = HttpRequest.newBuilder(uri).build();
try {
HttpResponse<String> response = client.send(req, HttpResponse.BodyHandlers.ofString());
String body = response.body();
body.lines().limit(5).forEach(System.out::println);
} catch (IOException e) {
System.out.println("IOException: " + e.getMessage());
} catch (InterruptedException e) {
System.out.println("InterruptedException: " + e.getMessage());
}
System.out.println("Complete!");
}
}
サーバ(プログラム実行後、ブラウザで http://localhost:8880/ にアクセスできる)
package org.example;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class Main {
public static void main(String[] args) throws IOException {
var server = new ServerSocket(8880);
while (true) {
try (Socket soc = server.accept();
var isr = new InputStreamReader(soc.getInputStream());
var bur = new BufferedReader(isr);
var w = new PrintWriter(soc.getOutputStream()))
{
System.out.println("connect from " + soc.getInetAddress());
bur.lines()
.takeWhile(line -> !line.isEmpty())
.forEach(System.out::println);
w.println("""
HTTP/1.1 200 OK
Content-Type: text/html
<html>
<head><title>Hello</title></head>
<body><h1>Hello</h1><p>It works!</p></body>
</html>
""");
}
}
}
}
■列挙型
package org.example;
public class Main {
enum Gender {
MALE, FEMALE, NONE
}
public static void main(String[] args) {
var gender = Gender.NONE;
if (gender == Gender.MALE) {
System.out.println("男性");
} else if (gender == Gender.FEMALE) {
System.out.println("女性");
} else if (gender == Gender.NONE) {
System.out.println("不明");
}
}
}
■クラス
package org.example;
public class Main {
public static void main(String[] args) {
// クラスの利用
var user = new User("Yamashita", 19);
System.out.println(user.name() + "さんの年齢は" + user.age() + "歳です。");
if (user.isAdult()) {
System.out.println(user.name() + "さんは成年です。");
} else {
System.out.println(user.name() + "さんは未成年です。");
}
}
}
/*
* クラス
*/
class User {
public String name;
public int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String name() {
return name;
}
public int age() {
return age;
}
public boolean isAdult() {
if (age >= 20) {
return true;
} else {
return false;
}
}
}
以下のようにレコードクラスを使うことで、クラスをシンプルに記述できる(Java16から利用可能)
インスタンス変数と同じ名前でゲッターが実行されるが、セッターは実装されない
getNmae()/setName() のような実装も選べるといいかと思ったが、インスタンス変数は原則普遍にするべき…ということだと思われる
package org.example;
public class Main {
public static void main(String[] args) {
// レコードクラスの利用
var user = new User("Yamashita", 19);
System.out.println(user.name() + "さんの年齢は" + user.age() + "歳です。");
if (user.isAdult()) {
System.out.println(user.name() + "さんは成年です。");
} else {
System.out.println(user.name() + "さんは未成年です。");
}
}
/*
* レコードクラス
*/
record User(String name, int age) {
public boolean isAdult() {
if (age >= 20) {
return true;
} else {
return false;
}
}
}
}
Main.java と同じ場所に例えば User.java を作成すると、以下のようにメインのプログラムから呼び出すことができる
package org.example;
public class User {
public String name;
public int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String name() {
return name;
}
public int age() {
return age;
}
public boolean isAdult() {
if (age >= 20) {
return true;
} else {
return false;
}
}
}
package org.example;
public class Main {
public static void main(String[] args) {
// クラスの利用
var user = new User("Yamashita", 19);
System.out.println(user.name() + "さんの年齢は" + user.age() + "歳です。");
if (user.isAdult()) {
System.out.println(user.name() + "さんは成年です。");
} else {
System.out.println(user.name() + "さんは未成年です。");
}
}
}