Javaの文字列入門

ここのところあまり更新できていなかったので、久々の投稿、今回はJavaの文字列についての扱いを簡単にまとめて見ます。

Javaでは文字列は標準クラス(Javaの言語機構に標準で含まれているクラス)のStringを使います。

String str = new String("Hello world");

こんな感じです。
あるいは、下記のような書き方でも宣言できます。

String str = "Hello world";

ただし、newを使うやり方だと無駄なインスタンスを使うことになってしまうので、通常はString str = "Hello world";のようにします。

文字列の扱いは、文字列用に用意されたStringクラスのメソッドを使うことで便利になります。

// length 文字列の長さを取得
String str1 = "apple";
int strlen = str1.length(); // 5

// substring 文字列の部分文字列を取得
// 1番目の引数:始まりの位置(0から始まる)
// 2番目の引数:終わりの位置(省略すると最後まで)
String str2 = "orange";
String str3 = str2.substring(2, 4); // ang
String str4 = str2.substring(0, 3); // oran
String str5 = str2.substring(3); // nge

// indexOf 指定された文字列が最初に現れる位置を返す(0が起点)
// 存在しない場合は-1が返される
String str6 = "banana";
int index1 = str6.indexOf("nan"); // 2
int index2 = str6.indexOf("non"); // -1

他にも文字列を扱うメソッドはたくさんあるので、詳しくは公式ドキュメント(Java8)を見てください。

後、文字列の比較はequalsというメソッドを用います。

String str7 = "Tokyo";
String str8 = "Tokyo";
String str9 = "Osaka";
boolean check1 = str7.equals(str8); // true
boolean check2 = str7.equals(str9); // false

こんな感じです。イコール(=)で比較するとメモリ領域を比較することになるので、必ずしも期待した結果にならないので気をつけてください。

文字列の結合はプラス(+)を使います。

String str10 = "Super";
String str11 = "Star";
String str12 = str10 + str11; // "SuperStar"

こんな感じです。ただし、何回も繰り返すとパフォーマンスが悪くなるので、このような場合はStringBuilderクラスを使って以下のようにします。

StringBuilder builder = new StringBuilder();
List<String> data = getData(); // getDataは文字列のリストを取得するメソッドとします
int dataSize = data.size();
for (int i = 0; i < dataSize; i++) {
    builder.append(data.get(i));
}
return builder.toString();

こんな感じで、いくつか気をつけるところがあったりしますが、うまく文字列処理ができるようになりたいものです。
文字列処理は正規表現を使うともっと複雑なことができたりしますが、それについては別の機会に紹介します。

ここ5年ほどのJavaを簡単に振り返ってみる

下の記事で転職先が決まって久しぶりにJavaを使うことになると書いたが、ここでここ5年ほどのJavaの動向を振り返ってみようと思う。

WikipediaのページJDK公式ページによると、大体こんな感じ。
2014年3月 Java8(ラムダ式、型アノテーション、Date and Time API 、JavaFX(Swingより高機能なGUIツール)など)
2017年9月 Java9(言語レベルでのモジュール化のサポートなど)
2018年3月 Java10(ローカル変数型推論など)
2018年9月 Java11(ネストベースのアクセスコントロールなど、OracleJDKの有償化!!
2019年3月 Java12(JVM定数のAPIなど)

こうして見ると、5年前のJava8で色々な機能が追加されたのが目につく。中でも、今更ながらラムダ式の導入はかなり大きかったのではないかと。
ラムダ式の例としては、こんな感じ。

package Lambdatest;
import java.util.function.*;

public class LambdaTest {
	public static void main(String[] args) {
		double x1 = 3.0;
		double y1 = 4.0;
		BiFunction<Double, Double, Double> z = (x, y) -> Math.sqrt(x * x + y * y);
		System.out.println(z.apply(x1, y1));
	}
}

これと同じことをラムダ式を使わずにやろうとすると、無名クラスを使ったり、結構ややこしいことになるんではと思う。
そういえば、C++も言語仕様が大きく追加されたC++11からラムダ式が使えるようになったんだったな。

他にも色々な機能が増えて、ここ数年で本当に進歩したんだなあ。とはいえ、いいことばかりではなくJava11からOracleJDKが有償化されてしまった(個人で使う分には大丈夫みたいですが)のは多くの人にとっては痛そうですね。。。OpenJDKの方は無償で使うことができるのですが、サポート期間が短かったりするので、悩みどころですね。

追記
Qiitaのコメント欄で情報をいただいたので、少しだけ追記します。
Amazon CorrettoというOpenJDK互換の無償のディストリビューションがあるようです。インストール方法などはこちらを参考にして見てください。