前回の復習
兼ねて練習問題クリア。全部まとめて解答。
import java.util.Calendar;
import java.util.Date;
import java.util.Random;
public class JavaPracticeSample {
public static void main(String[] args) {
//1. Dateクラスを使って現在が何月かを表示。
Date date = new Date();
System.out.println(date.getMonth() + 1);
//2. Calendarクラスを使って現在が何月かを表示。
//Date.getMonth()は非推奨なので、Calendarクラスから下記のように呼び出す。
Calendar cal = Calendar.getInstance();
System.out.println(cal.get(Calendar.MONTH) + 1);
//3. RandomクラスのnextBooleanメソッドを使って条件分岐処理を行う。
//if(new Random().nextBoolean()){} みたいにも書ける。
Random rand = new Random();
boolean isLucky = rand.nextBoolean();
if(isLucky){
System.out.println("ラッキー");
}else{
System.out.println("アンラッキー");
}
}
}
文字列を扱う
Stringクラスの利用
Stringクラスは実はchar配列をフィールドに持ったクラス。
以下は代表的なメソッド。
public class StringSample {
public static void main(String[] args) {
String str = new String("ABC");
System.out.println(str);
//こういう書き方もできる。
char[] cc = new char[]{'A','B','C'};
String str2 = new String(cc);
System.out.println(str2);
byte[] bb = {0x41, 0x42, 0x43};
String str3 = new String(bb);
System.out.println(str3);
//charAt 指定した位置の文字を抜き出す
System.out.println(str2.charAt(1));
//length 文字列の長さを返す
System.out.println(str2.length());
String s1 = "abc";
String s2 = "abc";
String s3 = "ABC";
//equals 文字列の比較(大文字小文字を区別)
System.out.println(s1.equals(s2)); //true
System.out.println(s1.equals(s3)); //false
//equalsIgnoreCase 文字列の比較(大文字小文字を無視)
System.out.println(s1.equalsIgnoreCase(s2)); //true
System.out.println(s1.equalsIgnoreCase(s3)); //true
//indexOf 指定文字列が含まれる位置を返す
int pos = s1.indexOf("bc");
System.out.println(pos);
//含まれない場合は -1を返す
int pos2 = s1.indexOf("d");
System.out.println(pos2);
String s4 = "ABCABCABC";
//indexOf 複数発見された場合は、最初の文字の位置を返すが、
//lastIndexOfは最後の位置を返す
int pos3 = s4.lastIndexOf("C");
System.out.println(pos3);
//startsWith 始まりの文字列が指定文字列か、真偽値で返す
//endWith 終わりの文字列が指定文字列か、真偽値で返す
System.out.println(s4.startsWith("A"));
System.out.println(s4.endsWith("D"));
//substring 指定位置の文字列を返す、引数の取り方で、2通りある
String s5 = "abcdefg";
System.out.println(s5.substring(5));
System.out.println(s5.substring(2,3));
//trim 前後の空白を削除する(単語間の空白は削除されない)
String s6 = " hoge fuga hoge ";
System.out.println(s6.trim());
//replace 文字列の置換
String s7 = "Hello, world!";
System.out.println(s7.replace('o','0'));
//replaceAll 正規表現で文字列の置換が行える
//replaceFirst 正規表現で文字列の置換が行える(最初に一致したもののみ)
//今回割愛
//split 指定文字で区切り、配列で返す
String s8 = "春はあけぼの、やうやう白くなりゆく山際、少しあかりて、紫だちたる雲の細くたなびきたる";
String[] sArr = s8.split("、");
//以前やった配列の要素に対するループ処理
for(String s9 : sArr){
System.out.println(s9);
}
//format 文字列を指定した書式でフォーマットして返す。printfと同じ形式が利用できる(未学習)
//0フィルで5桁のフォーマットで表示
String s10 = String.format("[%05d]", 12);
System.out.println(s10);
}
}
Unicode
Javaでは文字を16bitのUnicodeで表現する。コンピュータの中では文字も数値として扱わせ、数値と文字を対応させたものが文字コード。Shift_JISやEUC、UTF-8などがある。¥u3042¥u3044¥u3046
で「あいう」を表現する。
文字列の比較
equalsメソッドを使う。==での比較は、インスタンスが対象なため、インスタンスが異なる場合、文字列が同一でもfalseを返してしまう。そのため、Javaで文字列比較はequalsメソッドを使うこと。(newせずリテラルを代入する場合は、trueになる)
文字列の連結
文字列の連結は+で行うことが出来る。文字列ごStringインスタンスが生成されるため、
何度も連結する場合はStringBuilderクラスを利用する。
public class StringBuilderSample {
public static void main(String[] args) {
StringBuilder sb = new StringBuilder();
sb.append("オラ");
sb.append("悟空。");
//prependメソッドないので、そういう処理はinsert(0,str);
sb.insert(0, "オッス!");
sb.append("いっちょやってみっか!");
System.out.println(sb.toString());
}
}
文字列と数字との変換
文字列→数字の変換
java.lang.IntegerクラスのparseIntメソッドを使う。
数字→文字列の変換
java.lang.IntegerクラスのtoStringメソッドを使う。
public class ConvertSample {
public static void main(String[] args) {
int i = 1000;
double d = 1000;
String s = "500";
//文字列から数字への変換
int sum = Integer.parseInt(s) + i;
System.out.println("合計は" + sum + "です");
//数字から文字列への変換
String sentense = s + Integer.toString(i);
System.out.println(sentense);
//数字から文字列への変換
String sentense2 = s + String.valueOf(i);
System.out.println(sentense2);
//Doubleの場合はDouble#toString, Double#parseDouble を使う。
double doubleSum = Double.parseDouble(s) + d;
System.out.println(doubleSum);
String sentense3 = s + Double.toString(d);
System.out.println(sentense3);
//String#valueOfはデータ型を各種引数に持つオーバーロード(多重定義)されたメソッド
String sentense4 = s + String.valueOf(d);
System.out.println(sentense4);
}
}
ラッパークラス
Integer,Doubleなどのクラスはintやdoubleなどの基本データ型を扱うためのクラスで、ラッパークラスと呼ばれる。
- 基本データ型をオブジェクトとして扱う
- 他の型と変換を行うユーティリティメソッドを提供する
種類 | 基本データ型 | ラッパークラス |
---|---|---|
論理 | boolean | Boolean |
文字 | char | Character |
整数 | byte | Byte |
short | Short | |
int | Integer | |
long | Long | |
浮動小数 | float | Float |
double | Double |
public class WrapperSample {
public static void main(String[] args) {
/* 1. 基本データ型からラッパークラスへ変換 */
//基本データ型からラッパークラスへの変換の例: コンストラクタ
Integer n = new Integer(12);
//staticなメソッドvalueOfを使って行うことも出来る
Integer n2 = Integer.valueOf(12);
/* 2. 文字列からラッパークラスへの変換 */
//コンストラクタ, valueOfメソッドには引数に文字列を渡しても型キャストされる
Integer n3 = new Integer("12");
/* 3. ラッパークラスから基本データ型への変換 */
//ラッパークラスから基本データ型への変換はintValueメソッドなどのxxxValueメソッドを利用する。
Integer n4 = new Integer(12);
int num = n4.intValue();
/* 4. ラッパークラスから文字列への変換 */
Integer n5 = new Integer(12);
String s = n5.toString();
/* 5. 文字列から基本データ型への変換 */
int num2 = Integer.parseInt("12");
}
}
ラッパークラスの定数
//ラッパークラスの定数:Integer型の定数の例
int max = Integer.MAX_VALUE;
int min = Integer.MIN_VALUE;
System.out.println("MAX_VALUE : " + max + "\nMIN_VALUE : " + min );
//MAX_VALUE : 2147483647
//MIN_VALUE : -2147483648
オートボクシング
Javaは基本データ型とラッパークラスの変換が代入時に自動で行われる。が例外が発生する可能性があるため、明示的に変換を行うほうが良いようだ。
//以下は同義らしい
Integer n = new Integer(12);
int num = n.intValue();
Integer n = 12;
int num = n;
数字のフォーマット
以下のコードに内容をまとめた。
import java.text.DecimalFormat;
import java.text.ParseException;
public class FormatSample {
public static void main(String[] args){
/* 数値から文字列へのフォーマット変換の例 */
//コンストラクタ
DecimalFormat df = new DecimalFormat("#.##");
//
String text = df.format(1.23456789);
System.out.println(text);
//#の場合、少ないと桁減る。多い場合は桁が増える。
DecimalFormat df2 = new DecimalFormat("####");
String text2 = df2.format(125);
System.out.println(text2);
//0の場合は0フィルしてくれる。多い場合は桁が増える。
DecimalFormat df3 = new DecimalFormat("0000");
String text3 = df3.format(125);
System.out.println(text3);
/* 文字列から数値へのフォーマット変換の例 */
DecimalFormat df5 = new DecimalFormat("###,###");
Number num2;
try {
num2 = df5.parse("120,000");
int n2 = num2.intValue();
System.out.println(n2);
} catch (ParseException e) {
// TODO 自動生成された catch ブロック
e.printStackTrace();
}
}
}
parseExceptionの書き方でEclipseでエラーが何回かでたので、修正するとエラーがでなくなったのでOKとした。
問題
BMI値の計算ばっかりしてる。
import java.text.DecimalFormat;
public class BMIPractice {
public static void main(String[] args) {
double height = Double.parseDouble(args[0]) / 100;
double weight = Double.parseDouble(args[1]);
double bmi = weight / Math.pow(height, 2);
DecimalFormat df = new DecimalFormat("#.##");
String bmiStr = df.format(bmi);
System.out.println("BMI値 : " + bmiStr);
}
}
例外処理
public class ThrowError {
public static void main(String[] args) {
int result = divOneTwo(args);
System.out.println("result : " + result);
}
static int divOneTwo(String[] args){
return Integer.parseInt(args[0]) / Integer.parseInt(args[1]);
}
}
上記コードに引数を与えず実行すると、Eclipseのコンソールに例外が表示される。
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at ThrowError.divOneTwo(ThrowError.java:8)
at ThrowError.main(ThrowError.java:4)
8行目、その呼び出し元である4行目、さらにその大元であるmainメソッドで、例外が発生することが表示されている。例外が発生すると、さかのぼって例外がスローされて、呼び出し元のメソッド(今回はmainメソッド)まで処理が戻される(例外発生以後のコードは実行されない)。java.lang.ArrayIndexOutOfBoundsException: 0
はスタックトレースと呼ばれ、例外の発生場所や、原因を追跡するのに役立つ。
javadocで例外クラスを見る
ArrayIndexOutOfBoundsException (Java Platform SE 8 )
java.lang.ArrayIndexOutOfBoundsException: 0
の末尾のゼロは、args配列の(?インデックス?)0番目にアクセスした時に起こったエラーということらしい。試しに引数を本来2つのところ、1つだけ与えて実行してみたところ、例外表示の末尾の数字は1になった。
標準ライブラリ内部からの例外スロー
引数を文字にした場合、
Exception in thread "main" java.lang.NumberFormatException: For input string: "a"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Integer.parseInt(Integer.java:580)
at java.lang.Integer.parseInt(Integer.java:615)
at ThrowError.divOneTwo(ThrowError.java:8)
at ThrowError.main(ThrowError.java:4)
というエラーがでる。javadocでInteger.parseIntの項目を確認。NumberFormattingExceptionが例外としてスローされる可能性がある、と書かれている。
try ... catch文
これまでも使ってきているので、省略。コードで理解する。
public class ExceptionSample {
public static void main(String[] args) {
try{
int result = divOneTwo(args);
System.out.println("result : " + result);
}
catch(ArrayIndexOutOfBoundsException e){
System.out.println("ArrayIndexOutOfBoundsExceptionをキャッチしました。");
}
catch(NumberFormatException e){
System.out.println("NumberFormatExceptionをキャッチしました。");
}
catch(ArithmeticException e){
System.out.println("ArithmeticExceptionをキャッチしました。");
}
}
static int divOneTwo(String[] args){
return Integer.parseInt(args[0]) / Integer.parseInt(args[1]);
}
}
さらに、
catch(Exception e){
//...
}
で(ほぼ)全ての例外がキャッチできる。
その他
Eclipseのショートカット一覧とかみて試そうかなと思ったんだけど、まだそういう段階じゃなさそうなので、実行のショートカット(Cmd + fn + f11)だけ試してみた。MacのSpotlightのショートカット、特別必要ない気がしたのでオフにした。