Java奮闘記1 文字列 数値 変数とオブジェクト
はじめに
C言語を通して関数型プログラミングをしてきた。
今回からオブジェクト指向プログラミングに慣れるためにも、
Javaを学んでいこうと思う。
注意事項
C言語に通じる部分は基本省略している。
学びながら記事を書くので、内容の順番に意味はない。
私の誤解等あると思うので、是非指摘してほしい。
文字列
Stringクラス
Stringクラスは読み込み専用文字列のクラス
Stringクラスで作る文字列オブジェクトは文字列の内容を変更できない。
Stringクラスメソッド
これらを踏まえたうえでStringクラスメソッドの説明に移る。
詳しくはこちらのサイトをご覧いただきたい。↓
docs.oracle.com
・charAt(int index)...指定したindexの文字を取得。
・compareTo(String another)...2つの文字列をUnicode値に基づいて辞書順比較。strcmp関数みたいな。
・compareToIgnoreCase...2つの文字列の大文字小文字の違いを無視して辞書順比較。
//String s = new String("abc")でも良いが無駄なオブジェクト生成 //文字列リテラルは暗黙的にStringオブジェクトを生成する String s = "abc"; String t = "ABC"; //正の値 System.out.println(s.compareTo(t)); //負の値 System.out.println(s.compareTo("def")); //lengthの差(-3) System.out.println(s.compareTo("abcdef")); //0 System.out.println(s.compareToIgnoreCase(t));
・contains...指定した文字列が含まれていたらtrue。
・equals(Object ob)...このオブジェクトと同じ文字シーケンスを表すStringオブジェクトである場合にだけtrue。
・length...文字列の長さを返す。Unicodeコード単位の数。
・indexOf...指定した文字列が最初に出てくる位置のindexを返す。なければ-1。
・isEmpty...空文字列のときのみtrue。
・split...文字列を指定された正規表現に一致する位置で分割。
String s = "abc,e..f"; String[] ele = s.split(","); String[] ele2 = s.split("\\."); //"abc", "e..f" for(int i = 0; i < ele.length; i++) { System.out.println(ele[i]); } //"abc,e", "", "f" for(int i = 0; i < ele2.length; i++) { System.out.println(ele2[i]); }
・startsWith...指定した文字列から始まればtrue。
・endsWith...指定した文字列で終わればtrue。
・substring(int beginIndex)...beginIndexから始まる文字列を返す。
・substring(int beginIndex, int endIndex)...beginIndex以上endIndex未満までの文字列を返す。
・replace(CharSequence target, CharSequence replacement)...
targetに一致する部分文字シーケンスをreplacementに置き換えた文字列を返す。
String s = "ababab"; //aBaBaB System.out.println(s.replace("b", "B")); //ababab(元の文字列に変化なし) System.out.println(s); //CCCbab(変換は先頭から) System.out.println(s.replace("aba", "CCC"));
・trim...先頭と末尾の空白を削除した文字列を返す。
StringBuilderクラス
StringBuilderクラスは変更可能文字列クラス。
読み込み専用の文字列はStringクラス、変更可能な文字列はStringBuilderクラスという考えでいく。
StringBuilderクラスメソッド
詳しくはこちら↓
docs.oracle.com
・append...指定した文字列を末尾に追加。
・delete(int startIndex, int endIndex)...指定したindex間の文字列を削除。
・insert(int index, ???)...文字列を挿入する位置のindex、文字列(など)。
・replace(int beginIndex, int endIndex, String str)...
文字列のbeginIndex以上、endIndex未満の部分を文字列strに変換する。
・void setCharAt(int index, char c)...indexの文字をcに変換。
・String substring(int begin, int end)...begin以上end未満のindexの部分文字列を取得。
StringBuilder s = new StringBuilder("abc"); String t = "AAA"; //s = "abcdef" System.out.println(s.append("def")); //s = "ef" System.out.println(s.delete(0, 4)); //s = "eAAAf" System.out.println(s.insert(1, t)); //s = "e12Af" System.out.println(s.replace(1, 3, "12")); s.setCharAt(1, 'Z'); //s = "eZ2Af" System.out.println(s); //Z2を出力 System.out.println(s.substring(1, 3)); //eZ2Af System.out.println(s);
StringオブジェクトとStringBuilderオブジェクトの相互変換
//String → StringBuilder String s = "abc"; StringBuilder sb = new StringBuilder(s); //StringBuilder → String StringBuilder sb = new StringBuilder("abc"); String s = sb.toString();
文字列の結合
・文字列リテラル同士の結合はコンパイル時に行われるため、実行効率に変化なし。
String s = "abcdef"; String t = "abc" + "def";
・文字列の結合は暗黙的にStringBuilderオブジェクトを生成し、appendメソッドを呼んでいる。
以下のコードは...
String s = "abc"; s += "def";
実際には...
String s = "abc"; String t = "def"; StringBuilder sb = new StringBuilder(); sb.append(s); sb.append(t); s = sb.toString();
+演算子ではなくappendを使おう
数値
ビット長
・byte: 8
・char: 16
・short: 16
・int: 32
・long: 64
・float: 32
・double: 64
数値クラス
概要
数値基本型に対応する数値クラス(数値ラッパークラスと呼ばれる)がある。
数値クラスを使う場面は以下の通り
・数値をオブジェクトとして扱いたい場合
・特にコレクションの要素に数値を扱う場合
数値オブジェクトの利用
new演算子ではなく、valueOfクラスメソッドを使うことを推奨。
valueOfメソッドでは同じオブジェクトを再利用できる可能性があるためである。
Integer i = Integer.valueOf(7);
Booleanクラスの注意点
Boolean型変数はnullになる可能性があり、true、false、nullの3状態値である。
BooleanオブジェクトにはBoolean.TRUEかBoolean.FALSEのどちらかが必ず代入されているようにするべきである。
ボクシング変換
なんとJavaでボクシングができるのである。
...というのは冗談で
ボクシング変換は基本型数値と数値オブジェクトを自動的に変換する仕組み。
ボクシング変換を利用するとあたかも基本型の数値をオブジェクトのように扱える。
List<Integer> list = new ArrayList<>(); list.add(1);
逆に数値オブジェクトから基本型数値への変換をアンボクシング変換という。
int i = list.get(0);
暗黙にオブジェクト生成が起きることを忘れてはいけない。
次のコードは
Integerオブジェクトをint型整数にアンボクシング変換
→インクリメント演算
→演算結果をIntegerオブジェクトにボクシング変換
という流れになるので効率的ではない
Integer i = 0; //ボクシング変換 i++; //アンボクシング変換とボクシング変換
変数とオブジェクト
参照型変数の代入
参照型変数への代入とは、変数の値にオブジェクトの参照をセットすること
StringBuilder sb = new StringBuilder();
変数の宣言(StringBuilder sb)、オブジェクトの生成(new StringBuilder())。
名無しのオブジェクトを名前で呼ぶための変数sb。
変数sbはStringBuilderオブジェクトの参照を持つ。
また参照をセットした変数を他の変数に代入すると、どちらも同じ参照となる。
StringBuilder sb = new StringBuilder(); StringBuilder sb2 = sb; sb.append("ABC"); //ABCと出力 System.out.println(sb); sb2.append("DEF"); //どちらもABCDEFと出力 System.out.println(sb2); System.out.println(sb);
null参照
null値を持つ参照型変数に対する演算はNullPointerException実行時例外を引き起こす。
StringBuilder sb = null; sb.append("012"); //NullPointerException発生
nullチェック
StringBuilder sb = null; if(sb == null) { System.out.println("sb is null"); }
Java7,Java8以降ではObjectsクラスにnullチェックのメソッドがある。
import java.util.Objects; public class Sampler{ public static void main(String[] args) { StringBuilder sb = null; if(Objects.isNull(sb)); //真 if(Objects.nonNull(sb)); //偽 if(Objects.equals(sb, null)); //真 } }
変数の型、オブジェクトの型
変数とオブジェクトの型が一致していれば、そのオブジェクトの参照を変数に代入できる。
StringBuilder sb = new StringBuilder(); // OK StringBuilder sb = new String(); // コンパイルエラー
変数が参照するオブジェクトに対して行える操作は、変数の型で決まる。
sb.length(); // OK sb.size(); // コンパイルエラー
変数のデフォルト初期値
・参照型 : null
・boolean : false
・char : '\u0000'
・byte, short, int, long : 0
・float, double : +0.0
final変数
final修飾子を指定した変数をfinal変数と呼ぶ。
final変数は再代入不可の変数である。
final int n = 1; n = 2; // コンパイルエラー
参照型final変数の場合注意が必要。
参照先の再代入は不可だが、参照するオブジェクト自体の変更は可能。
final StringBuilder sb = new StringBuilder("ABC"); StringBuilder sb2 = new StringBuilder("DEF"); sb = sb2; // コンパイルエラー sb.append("DEF"); // OK
参考文献
・一番かんたんなJava入門 URL: https://nobuo-create.net/category/java-beginner/
・パーフェクトJava【改訂2版】 著: 井上 誠一郎 / 永井 雅人 (2014/12)