Javaメモ(silver, gold)
Java SE 11について
- 各資格レベル
-
受験の方法
- oracle certviewにログイン
- “manage exam at pearson VUE”で試験予約を行う
run/execute
javac Main.java-
java Main- 拡張子なし
package
- パッケージは慣習としてドメイン名を逆にしたものを用いるが絶対ではない
- すべてのクラスはパッケージに属するがパッケージを省略すると匿名パッケージになる
-
java.langはimportしなくても使える - 同じパッケージもimportしなくても使える
- 名前のあるpackageに無名のパッケージを暗黙的に読み込むことはできない
main
- public + staticである必要がある
- オーバードード可能
run
-
java Testorjava Test.java - バックスラッシュでエスケープ
-
"a "b->a bという文字列で解釈される
types
-
booleanは存在するがboolはない - 数字リテラルの先頭で数字表現が変わる
-
0b-> 2進数 -
0x-> 16進数 -
0-> 8進数
-
-
_リテラル- 数字の先頭と最後はNG
- 記号の前後はNG
-
$,_は変数として使える -
varは型推論を行うがローカル変数の推論だけ(generic class等は作れない) -
StringBuilder- デフォルトで16のバッファをもつ
-
++,--- その場でインクリメント、デクリメントする
- 同値判定
-
Objectのequalsをオーバーライドする -
x.equals(null)はfalseを保証する必要がある -
コンスタントプールとインスタンス-
==では一致しないが、equalsでは一致する
-
-
-
cast
- NG
- int = float;
- OK
- float = int;
- NG
String
-
Stringは参照渡しにならずにコピーわたしになる? -
replaceはすべて変えるreplace all -
substringがslice -
concatが文字列連結 -
100 + "yen"->100yen - リテラルのインスタンスで
==で比較する際の挙動がだいぶ違う - C++の
char*を取り出すには.intern()でアクセスする-
.intern()の内容は==で比較可能
-
array
- C++のようにスタックに初期化みたいなことはできない
- 型だけを初期化はできる
- リテラルだけでなく動的変数でもできる
- ネストされた初期化は子だけサイズ宣言はできない
- NG
int[][] a = new int[][3]int[] c = new int[2]{2, 3};
- OK
int[][] a = new int[3][]int[] d = {};int[] b = new int[]{2, 3};
- NG
- 初期化リスト
String[] array = {1, 2, 3, 4}
-
mismatch- indexの最初から見ていて一致しない最初のindex
-
compare- sortした上で最初に一致しないindex
map
- Tupleの受け取りに
Map.Entryが存在するe.getKey()e.getValue()
-
nullもキーになる -
Mapクラス
- 初期化
Map<Integer, String> map = Map.of(1, "a", 2, "b")
- 初期化
-
merge
- キーが既にある時のvalueの操作に使う
map.merge("key1", "val1", (v1, v2) -> { ... });- 仮にキーが無いと、”val1”が新規に作成される
- キーが既にある時のvalueの操作に使う
comparetor, comparable
-
comparetor- comparableはsort関数の引数に入れるためのもの
- 匿名クラスで
Collections.sortの引数に与えてソートするなど -
compare関数をオーバーライドする -
streamで使えるcomparator lambda
-
streamList.sorted(Comparator.comparing(Book::getId).thenComparing(Book::getTitle)).forEach(s -> System.out.println(s.id + ":" + s.title));-> (id,title)でソート
-
-
comparable- comparatorとの違いはデータオブジェクトに組み込むもの
- 他のインスタンスとの差を定義する
- Treeへの埋め込みなど
-
compareTo関数をオーバーライドする
switch
- OK
- int以下の数字
- enum
- オブジェクト型
- NG
- long以上
- boolean
-
break;を各ステートメントに記述しないと終了しない- 仮にbreakが存在しないと次の判別式に入る
- リテラルのみ判別条件に使用可能
for
-
for(Object a: array)のような表現のとき、aはコピー渡し - 初期化できる変数は同じ型のみ
-
for (int i = 0, long j = 10; true; i++) {}-> NG
-
equals
- Objectのequals関数をオーバーライドして使用するがデフォルトの引数がobject型なので、型を固定するとオーバーロードになってしまい、適切に動作しない
comparator
-
クラス内実装
- 比較を行うもの
-
left < right->-1のとき昇順 -
left < right->1のとき降順
-
クラス外実装
Collection.sort(arr, new Comparator<?>() { public int comprare(T t1, T t2) { return ... } })
arraylist, list
-
基本
- forで回しているときにremoveするとそのオペレーションは問題がないが、次に呼び出すときに例外が出る
- 初期化法
List.of(...)
-
Arraysクラス
- 初期化
Arrays.sort(ary1)Arrays.asList(...)
- 初期化
-
ArrayList
List<String> a = new ArrayList<>();- mutable
-
List
List<String> a = List.of();- immutable
-
List.copyOf(list)-
ArrayListなどをcopyできるがcopyしてもイミュータブルのListオブジェクトになってしまう
-
treeset, treemap
- 順位がある
-
TreeMap<String, ?>ならば、辞書順となる -
順序を指定してインスタンス作成
Set<Employee> s = new TreeSet<>((e1, e2) -> e1.getId() - e2.getId())
thread
-
実行
-
Threadを継承してrun関数をオーバーライドして利用する -
Runnnableインターフェースを継承してオーバーライドして利用する
-
-
実装
new Thread(new Runnnable() { public void run() { ... } }).start()new Thread(() -> {...}).start()
-
members
getPriority()setPriority(Integer)getName()sleep(long)join()-
yield()-> 一時的に停止する -
interrupt()-> 割り込みを入れる
-
synchronized
- 関数の前に
synchronizedをつけることでオブジェクトが利用されたとき排他制御を行う
- 関数の前に
-
atomic
-
AtomicIntegerなどで宣言するcount.incrementAndGet()
-
-
並列コレクション
VectorHashtable-
BlockingQueue,ConcurrentHashMap,ConcurrentLinkedDeque,CopyOnWriteArrayList -
ConcurrentHashMap
ロック・ストライピングsize メソッドや isEmpty メソッドの厳密性要件が弱め- iteratorはweakly consistent
-
CopyOnWriteArrayList
- 変更処理中に他のスレッドが読み取りを行う場合、コピー前のリストが返却される
-
java.util.concurrent.CyclicBarrier
- 各スレッドの足並みを合わせる
- バリアに到達すると、他のスレッドがバリアに到達するまで待機(await)
-
Executor
- スレッド・プールの実装
- ライフサイクル管理や監視、統計収集
Executor executor = Executors.newScheduledThreadPool(3);
- *java.util.concurrent.Callable
* - Runnableと違い戻り値を戻せる
Future<String> future = service.submit(new MyTask());
- *Future
*
lambda
- 実質final
- 同じスコープの変数名と同じ変数をlambdaで使うことはできない
- lambda内でlambdaを包括するscopeの変数にアクセスできるが変更はできない
-
Predicate- 評価専用関数でbool帰る
-
or,andで関数合成、negate()で反転
-
Supplier- 引数を受け取らない
-
Consumer- 引数を受け取るが処理をするだけ
-
returnの省略- ブレース記号を省略した場合に利用可能
- ブレースがあるときは省略不可
-
andThen- 関数合成
stream
-
基本の型
- コレクション
stream<T>
- プリミティブ型
IntStreamDoubleStream
- コレクション
-
例
list.stream().map(...).forEach(...)
-
range
-
IntStream.range(1,6).forEach(System.out::print)-> “12345” -
IntStream.rangeClosed(1,6).forEach(System.out::print)-> “123456”
-
-
評価式
allMatch(...)anyMatch(...)-
noneMatch(...)-> どの要素にもマッチしない
-
reduce
-
Stream.of(10, 20, 30).reduce(0, (a, b) -> a + b)-> 60
-
-
toArray
- streamからarrayに変換
-
operations
filterdistinctlimit-
skip(long n)-> n個を破棄した残り mapflatMap-
sortedorsorted(Comparetor<?>) -
peek-> consumerを期待して、streamを返す。デバッグ等
-
collectors
toList()joining("hoge")-
summingInt()-> 合計値 -
averageInt()-> 平均値 toSet()toMap(f1, f2)-
minBy,maxBy -
forEach-> forEachは終端操作なので何度も呼び出せる要素ではない
-
parallelStream()
- パラレル化する
-
generate
- 無限stream
-
Stream<Double> randoms = Stream.generate(Math::random);-> ランダム -
Stream<BigInteger> integers = Stream.iterate(BigInteger.ONE, n -> n.add(BigInteger.ONE));-> 無限カウンター
-
concat
Stream<String> combined = Stream.concat(letters("Hello"), letters("World"));
-
grouping
Map<String, List<Locale>> countryToLocales = locales.collect( Collectors.groupingBy(Locale::getCountry));
optional
-
nullの代替 -
初期化
Optional<Integer> op = Optional.enmpty();Optional<Integer> op = Optional.of(1);
-
check
-
op.isPresent()-> 値があるとき -
op.isEmpty()-> 値がないとき
-
-
get
op.get()
interface class
-
通常
- C++のヘッダーファイルのようなもの
- シグネチャ
- アクセス修飾子は指定しないとpublicになる
- interfaceに実装を入れるには
defaultが必要 - interfaceはfinalにできない
- 許可するシグネチャは
public,abstract,default
- interfaceの方で受けるとき、実装があるsubclassまで探して実行
-
ダイヤモンド継承をしたとき
- 衝突する実装が2つ以上のinterfaceにあるときoverrideしないとエラーが起きる
-
匿名クラスでインスタンスを作成できる
-
public interface Foo{ public void doIt(); }-
new Foo() { public void doIt(){ System.out.println("YES!"); } }.doIt()-> “YES!”
-
-
-
function interface
- 単一の抽象メソッドを持つ必要がある
- static, defaultのメソッドを抽象メソッドを定義可能
-
@FunctionalInterfaceをつけることで明示化可能 - interfaceから実装するときシグネチャを変えることはできない
signature
-
種類
public-
protected- 同じクラス,同一パッケージ,違うパッケージのサブクラスから参照可能
-
default- 同じクラス,同一パッケージ,同じパッケージのサブクラスから参照可能
-
private- 同じクラスからのみ
inference type
-
var
- OK
var a = "hello"var a = new int[]{10, 20}
- NG
var a = 100;var a = {10, 20}
- OK
-
varの使用制限
-
varはローカル変数のみ使える - メンバ変数には用いることができない
-
abstract class
- インスタンスを生成できない
- すべての関数をoverrideする必要はない
- overrideは戻り値の型を変えられる
- 継承関係ではsubclassは継承元よりゆるいアクセス修飾子を定義できる
- interface classと似ているが、具象である具体的な実装を入れられる
- 具象にしない場合は関数の前に
abstractをつける
inherit
- subclassでコンストラクタで
super()を省略してもsuper()がコンパイラで挿入される - シグネチャは同様のものが継承される
- シグネチャを省略すると同じ名前空間で継承されたものからはアクセスできる
- 継承してオーバーロードすると、より厳密な方にオーバーロードされる. ListはCollectionの継承で作られているので、CollectionのIFよりListが優先される
- 親が
privateなら子は親のprivateにアクセスできない - 子クラスが親クラスの関数をoverrideするときは、かならず同じかそれよりゆるいシグネチャである必要がある
-
superでアクセスできるのは直上のclassだけで二段階上にアクセスする方法はないらしい
overloading
- 入力がどうなっても良いが、出力の型を変えることができない
- シグネチャ(protected, private, public)は変えることはできない
override
- 出力の型は同じかサブクラスである必要がある -> 共変戻り値
- シグネチャは同じかより緩いもの
constructor
- publicなコンストラクタは外部から関数として呼び出すことができる
- void, intとかの戻り値をつけると通常関数として解釈される
-
this(...)で自インスタンスのコンストラクタを呼び出せる - コンストラクタ内部で別のコンストラクタを呼ぶときは必ず最初に記述する(this(“hoge”))
- デフォルトコンストラクタは任意のコンストラクタ実装をしてしまうと生成されない
-
static methodではstatic 変数しかアクセスできない(通常のインスタンス変数にアクセスしようとするとエラーになる)
enum
- 暗黙的にfinalクラスとしてコンパイルされる
- ほかのクラスを継承することができない
- 列挙定数にはいかなる修飾子もつけることができない
- 「public」または「パッケージ(修飾子なし)」
- 暗黙的に「private」として扱われる
-
public enum Day { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY}のように利用する -
.name(),toString()はstringを得る -
.valueOf("SUNDAY")はenum.SUNDAYを返す -
.values()は要素のリストを返す -
.ordinal()は列挙順を返す -
System.out.printなどでtoString()されたときの挙動はコンストラクタ+メンバ変数とメンバ変数をどう呼び出すかを定義したtoString関数で決定される - 任意のコンストラクタを埋め込めるが
privateである必要がある
inner class
- classの中にclassを生成する
-
Outer.Inner inner = new Outer().new Innter()のようなシンタックスになる
final
-
finalをつけた変数は定数として解釈されるので初期化されていないとエラーになる -
finalとabstractは併記できない -
finalは関数の引数になれる
initialization
- コンストラクタの前に置く
- コンストラクタの前に実行される処理
- static classではインスタンスを作らないと実行されない
-
static {...}で静的に宣言することもできる
generics
-
class Hoge<T> { private T var1; ... }のように書いて型パラメータを抽象化する - 型パラメータはプリミティブ型は利用できない
- 使用する際、
<?>のように記述することでその部分を再抽象化できる -
<T> void Func(){..}のように書くとgeneric methodにできる -
<T extends U>でUを上界とするTに限定できる -
<T super U>でUを下界とするTに限定できる
exceptions
-
illigal
- 到達不能なcacheブロックが存在するとき
-
try-cache-finallyは順序違反 - 必ず例外は継承関係の子から記す必要がある。親から記すとコンパイル時例外
-
return
-
cacheステートメントにreturnが存在してもfinally実行後に実行される -
cacheとfinallyどちらにもreturnがあるとき、最後に実行されたreturnの値が戻る
-
-
種類
-
非検査例外
-
RuntimeExceptionは非検査例外で明示的に関数に示さなくてもいい -
ArrayIndexOutOfBounds,ArrayStoreException,ClassCastException
-
-
検査例外
- 検査例外はJVM以外の外的要因でハンドルされるもの
- 必ず処理が求められる
- 例外とは別に
Errorというものがある -
AssertionError,StackOverFlow,NoClassDefFoundError,IOException,FileNotFoundException,ParseException,SQLException
-
非検査例外
-
variance
-
catch(NumberFormatException | ArithmeticException e) { ... }のように併記できる - 制限として継承関係のあるものは併記できない
-
-
throws
- 関数の後ろに定義することで例外が発生したときに関数の呼び出し元に通知する
- テクニックの一つとしてthrowを条件分岐するrethrowというものがある
-
try-with-resourecs
-
try(MyResource obj = new MyResource()){ ... }のような書き方のものでリソースを最後にclose()するのでリークしない -
cacheの処理が走る前にリソースのclose()が行われる - 使用するには
AutoCloseableインターフェースを実装する必要がある
-
-
assert
- 真値を返さないと
Errorを送出する- Errorはtry-cache-finallyでハンドルできる
assert( something > 0): "エラーです"-
java -ea Mainのように実行することで有効化できる
- 真値を返さないと
-
methods
getMessage()getLocalizedMessage()-
getCause()-> Exceptionのラップ関係の内部を取り出す getStackTrace()printStackTrace()
io/nio
- PythonのPathクラスのようなもの
- pathインスタンス
Path.get("something string path")
-
streamの種類
-
FileInputStream-> ファイルからバイト単位で読み込み -
FileOutputStream-> ファイルからバイト単位で書き込み -
DataInputStream-> 基本データを読み込む -
DataOutputStream-> 基本データを書き込む -
FileReader-> char単位で読み込む -
FileWriter-> char単位で書き込む -
BufferReader-> char単位でバッファリングして読み込む -
BufferWriter-> char単位でバッファリングして書き込む
-
-
Files
- 制限
- OS固有の操作は行えない
- chown, chmodなどは使えない
-
Filesによる操作Files.createDirectory(path)Files.createDirectories(path)Files.deleteIfExists(path)Files.delete(path)Files.copy(path1, path2, OPTION)Files.move(path1, path2, OPTION)-
Files.getAttribute(path, "OPTION")-> “size”, “creationTime”等 Files.walk(path).filter(s -> s.toString().endsWith(".jpg"))-
Files.size(path)-> ファイルサイズ
- 制限
-
出力に応じたクラス
-
bytes->InputStream,OutputStream -
text->Reader,Writer -
object(シリアライズ)->ObjectOutputStream+writeObject -
primitive->PrintStream,PrintWriter
-
- nioでファイルを読み込む例
String contents = new String(Files.readAllBytes( Paths.get("../gutenberg/alice30.txt")), StandardCharsets.UTF_8);byte[] bytes = Files.readAllBytes(path);List<String> lines = Files.readAllLines(path, charset);try (Stream<String> lines = Files.lines(path, charset)) {...}
- nioでファイルを書き込む
-
テキスト
Files.write(path, content.getBytes(charset), StandardOpenOption.APPEND);
-
テキスト
-
Pathオブジェクト
- 取得
FileSystems.getDefault().getPath("/tmp")Paths.get("/tmp")-
Path path = file.toPath()-> fileオブジェクトからpathオブジェクトに変換
- 操作
getFileName()getFileSystem()-
getName(int index)-> パスの要素をindexを指定 -
getNameCount()-> パスの要素数 getParent()getRoot()
- 取得
-
file systemの確認
-
FileSystems.getDefault()->sun.nio.fs.LinuxFileSystem@6a38e57f
-
console
-
初期化
Console console = System.console();String line = console.readLine();
-
パスワード
char[] pswd = console.readPassword();
jdbc
- 公式チュートリアル
-
syntax
jdbc:<protocol>:<name>jdbc:mysql://localhost:3306/golddb
-
drivermanager
con = DriverManager.getConnection(URL, "root", "password")-
Properties
- 概要 -> getConnectionnの引数に入れて認証を行うのも
- 例 ->
Properties connectionProps = new Properties(); connectionProps.put("user", this.userName); connectionProps.put("password", this.password); conn = DriverManager.getConnection( "jdbc:" + this.dbms + "://" + this.serverName + ":" + this.portNumber + "/", connectionProps);
-
statement
stmt = con.prepareStatement(sql)
-
cursol
ResultSet rs = stmt.exrcuteQuery()while(rs.next()) { rs.getInt(1), rs.getString(2) }
-
excute
int executeUpdate(String sql
-
ResultSet
- 予約キーワード
-
TYPE_FORWARD_ONLY-> 順方向 -
TYPE_SCROLL_INSENSITIVE-> 双方向,カーソル変更なし -
TYPE_SCROLL_SENSITIVE-> 双方向,カーソル変更あり
-
- スクロールメソッド
boolean absolute(int)boolean relative(int)boolean next()boolean previous()boolean first()void beforeFirst()boolean last()void afterLast()
- 更新
-
updateRow()-> 確定反映 -
updateString(int, String)-> 仮で内容の変更 -
updateInt(int, int)-> 仮で内容の変更
-
- 削除
deleteRow()
- 予約キーワード
-
batch update
- autocommitを無効にして、
stmt.executeBatch(); conn.commit();
- autocommitを無効にして、
-
secure coding
- update等を行うときに不正な値が入らないようにする
- アップデートしたい箇所は
?とするSQLを用意する PreparedStatement stmt = connection.prepareStatement(SQL)-
stmt.setString(1, "パスワード")のようにして値を入れる stmt.executeUpdate()
-
normalizer
Normalizer.normalize("正規化したいデータ", From.NFKC)
locales
- 使用できるlocales
Locale[] supportedLocales = NumberFormat.getAvailableLocales();
- 通貨表示
-
Locale loc = Locale.GERMAN; NumberFormat currFmt = NumberFormat.getCurrencyInstance(loc); double amt = 123456.78; String result = currFmt.format(amt);-> “123.456,78 €” - java.util.Currencyが存在する
-
- デフォルトのlocaleを選択
Locale locale = Locale.getDefault();
-
ListResourceBundle
- localeによって表示を変えるとき orange -> オレンジのような対応表を作成する
-
ListResourceBundleを継承しgetContentsをオーバーライドして使用する - 参考
security
serialize
-
Serializableをimplementsする -
ObjectOutputStreamでoos.writeObjcet(instance)のように書き込む -
ObjectInputStreamで(Inatance)ois.readObject()で読み込む -
除外されるメンバ変数
statictransient
modules
-
module-info.javaに記述exports ${PACKAGE_NAME}-
requires ${DEP}-
requires transitive ${DEP}-> 階層構造の自分を依存するmoduleに全てに伝搬させる
-
privides ${SERVICE} with ${SERVICE_PROVIDER}uses ${SERVICE}
- モジュールを含めて実行
java --module-path $DIR -m ${MAIN_CLASS}/${PACKAGE_PATH}
- デフォルトで組み込まれるmodule
java.base
- モジュールを表示
jmod describe-
java --describe-module-
exports hogehogeで出てきた要素がターゲットが依存しているモジュール
-
- コンパイル時に一時的にmoduleを追加
java ... --add-exports=... ...
- サービスローダー -> classpath以外で読み込む方法?
private static ServiceLoader<CodecSet> codecSetLoader = ServiceLoader.load(CodecSet.class);
annotations
-
種類
-
@Override-> 明示的にオーバーライド -
@FunctionalInterface-> 関数型のインターフェース -
@Deprecated-> 非推奨 -
@SuprressWarnings-> コンパイラ警告無効@suprresswarnings(value = {"..."})@suprresswarnings(value = {"...", "..."})@suprresswarnings({"...", "..."})
-
@SafeVarargs-> 可変長引数の警告無効
-
-
カスタム
public @interface Hogehoge { ... }- クラスのように定義する
- 抽象メソッドが変数のような役割
- enumも指定可能
-
メタアノテーション
-
@Documented-> Javadocに出力javadoc -d *.java
-
@Targget-> アノテーション要素を限定 -
@Retention-> アノテーションをクラスファイルまで持ち込むか -
@Inherit-> サブクラスにも引き継ぐ -
@Repeatable-> 複数回適応
-
api
-
Math.round- 四捨五入, 小数点何桁は指定できない
-
java.time- 日時関連
-
インスタンス作成
LocalDate.of(2020, java.time.Month.APRIL, 1);LocalDate.of(2020, 12, 1);
-
実装関連
-
TemporalAccessor-Temporal-LocalDataLocalTimeのような構造になっている
-
-
列挙型
DayOfWeekMonth
-
LocalDateTime
- 時間情報も含むLocalDate
LocalDate.parse("2016-06-12").atStartOfDay();
-
差分の計算
-
ChronoUnit.DAYS.addTo(inst, 5)-> 5日後を計算 -
ChronoUnit.DAYS.between(inst1, inst2)-> inst2とinst1の差の日数を計算 -
Period.between(inst1, inst2)-> 日数の差 -
Duration.between(inst1, inst2)-> 時間の差
-
-
timezone
-
ZoneId.systemDefault()-> Asia/Tokyo - ` ZoneId.getAvailableZoneIds()` -> ダンプ
-
-
formatter
DateTimeFormatter formatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)DateTimeFormatter formatter = DateTimeFormatter.BASIC_ISO_DATE-
DateTimeFormatter FOMATTER = DateTimeFormatter.ofPattern("MM/dd/yyyy 'at' hh:mm a z");-
String zdtString = FOMATTER.format(zdt);-> “07/15/2018 at 02:51 PM IST”
-
miscellaneous
- ローカル変数の初期化について
- primitive型でも初期化せずに利用するとコンパイルエラーが起きる