Arrays.asList(T... a) は、なぜ add や remove ができないのか?

Arrays.asList(T... a) というメソッドについてググると、「このメソッドで返ってくる List は、addremove ができないので注意しましょう」ということが良く書かれています。
でも、「なぜできないのか?」という点については書かれていないことが多いので、理由を説明します。


一言でまとめると「配列を List として扱えるようにラップするためのものだから」です。
(「変換するもの」ではないです)

そもそも、どう使うもの?

配列を List として扱いたいときに使います。


例えば、シャッフルするのに Collections.shuffle​(List list) という引数に List を取るメソッドはあるのですが、引数に配列を取るメソッドがありません。
そういうときに、 Collections.shuffle(Arrays.asList(a)) という風にラップすることで、引数に配列を渡せるようになります。


Arrays.asList(T... a) で返ってくるリストは元になった配列と連動しているので、この List の要素を書き換えれば配列の要素も書き換わります。

String[] array = new String[] {
    "aaa", "bbb", "ccc", "ddd", "eee"
};

// 配列を List にラップしてシャッフルする
Collections.shuffle(Arrays.asList(array));

// 元の配列が、ちゃんとシャッフルされている
// => [ccc, eee, ddd, bbb, aaa]
System.out.println(Arrays.toString(array));


Arrays.asList(T... a) が返すリストクラスの実装を見てみると、配列をラップしているだけなのがよく分かると思います。 ((この ArrayListjava.util.ArrayList とは別のクラスです。))

private static class ArrayList<E> extends AbstractList<E>
    implements RandomAccess, java.io.Serializable
{
    private final E[] a;

    ArrayList(E[] array) {
        a = Objects.requireNonNull(array);
    }

    @Override
    public int size() {
        return a.length;
    }

    @Override
    public E get(int index) {
        return a[index];
    }

なぜ add や remove ができないのか?

もし addremove を実装しようとすると、元になった配列の長さを変える必要があります。
しかし、Java では配列の長さを変えられません。


そのため、setget のような配列の中身に対して操作するメソッドは実装されていますが、addremove のような配列自体を変更する必要のあるメソッドは実装されていないのです。((正確には List インタフェースは addremove を実装する必要があるので、メソッドはあるけど UnsupportedOperationException をスローするという処理になっています)))

まとめ

明日の Java アドベントカレンダー、担当は null さんです。
誰か!書いて!!!


追記:
@opengl-8080 さんが書いてくださいました!
Doma2 でログ出力を制御する - Qiita

ジオシティーズのデータを保存する方法

2019年3月末で、ジオシティーズが閉鎖されることが決まりました。


これはつまり、過去のいろんな歴史的サイトも消えてしまうということ。
そうなる前に、ジオシティーズのデータを保存して置く方法をまとめました。

サイト全体をローカルに保存する

まず、Wget for Windows をインストールします。
その上で、スタートメニューから「コマンドプロンプト」を起動して、以下のコマンドを実行します。

"C:\Program Files (x86)\GnuWin32\bin\wget" --convert-links --mirror <トップページのURL>

これで、ページや画像、Java Script などが全部ダウンロードされます。
もし対象のページが更新されたときは、再度このコマンドを実行すれば差分だけダウンロードされます。


CSS で指定されている画像(背景とか)はダウンロードできないという弱点がありますが、おおむね実用には耐えられると思います。

Internet Archive に保存する

インターネット上に永久保存したい場合は、Internet Archive (Wayback Machine) へ。
https://archive.org/web/

  • "Save Page Now" のところに URL を入れる
  • "SAVE PAGE" をクリック

SavePageNow.png

今後、このサイトを見たくなったときは、URLで検索すれば見れるようになります。

注意点

ファイルをダウンロードすること、およびダウンロードしたファイルを個人で楽しむことは、法律上問題ありません。
著作権法第30条で、私的利用のための複製は認められているためです。


しかし、著作権者の許可無くインターネット上に再公開することは著作権法違反に当たります。
それは行わないようにしてください。


この記事は、違法行為を助長する意図はありません。

Java のリリース日とEOLのまとめ

Oracle JDK の場合

図にまとめてみました。
こうしてみると、サポート期間5~6年って結構長いなーと思います。


First Release Date Final Public Release Date Final Public Release Version
Java 1.3 2000年5月8日 2006年12月 Java 1.3.1 Update 20
Java 1.4 2002年2月6日 2008年10月 Java 1.4.2 Update 19
Java 5 2004年9月30日 2009年10月 Java 5 Update 22
Java 6 2006年12月11日 2013年4月 Java 6 Update 45
Java 7 2011年7月28日 2015年4月 Java 7 Update 80
Java 8 2014年3月18日 2019年1月 Java 8 Update 201
Java 9 2017年9月21日 2018年3月 Java 9.0.4
Java 10 2018年3月20日 2018年9月 Java 10.0.2
Java 11 2018年9月25日 - -

上記の Final Public Release Date は、Sun Microsystems または Oracle無償サポート期間です。

有償サポートを契約すると、さらに延長してサポートを受けられます。
この詳細は、JDKの新しいリリース・モデル、および提供ライセンスについて および Oracle Java SE サポート・ロードマップ をご覧ください。

サポート種別 Premier Support 期間 Extended Support 期間
Java 7 2019年7月 2022年7月
Java 8 2022年3月 2030年12月
Java 11 2023年9月 2026年9月

OpenJDK の場合

Oracle JDK 以外は各ベンダーによってサポート期間が異なります。

ディストリビューション Java 8 Java 11 資料
Red Hat OpenJDK (CentOSも準じる) 2026年5月 2024年10月 OpenJDK ライフサイクルおよびサポートポリシー | Red Hat Customer Portal
AdoptOpenJDK 2026年5月 2024年10月 Support | AdoptOpenJDK - Open source, prebuilt OpenJDK binaries
Amazon Corretto 2026年5月 2027年9月 よくある質問 - Amazon Corretto | AWS
Azul Zulu Enterprise 2030年12月 2027年9月 Azul Java Support Roadmap | Azul Support Lifecycle | Java 8 eol
BellSoft Liberica JDK 2030年3月 2027年3月 BellSoft Liberica JDK | BellSoft - Java Platform & Applications Experts

ディストリビューションごとの情報源は、@yamadamn さんの OpenJDKと各種JDKディストリビューションの情報源まとめ #minjava をご確認ください。

詳細

各 OpenJDK のサポートポリシーや比較については、@u-tanick さん、@yamadamn さんの資料をご確認ください。
JDKの長期商用サポート(LTS)の提供ベンダー比較(無償利用についても言及あり)(@u-tanick)
これからのJDK 何を選ぶ?どう選ぶ? (v1.2) in 熊本 (@yamadamn)

JJUG CCC 2018 Spring ( #jjug_ccc ) - セッション資料の一覧

JJUG CCC 2018 Spring に行ってきました!


実は、仕事では最近 Java から離れているのですが*1、それでも CCC (クロスコミュニティカンファレンス)と銘打ってるだけあってやっぱり参考になる話がいろいろありました。
特に、同じ業界の方も登壇されていて、自社とは違うアプローチの仕方をしているというのは刺激になりました。
なにかひとつでも、仕事で取り入れられたらなと思っています!


あと、懇親会のオフ会みたいな雰囲気も個人的にJJUG に参加する大きな理由の一つです。
いつも Twitter でフォローしている方とリアルにお会いできる貴重な場でした。お声がけしてくださったみなさんありがとうございました。*2
また次の JJUG CCC と Twitter 上でお会いしましょう!


さて、最後にいつものを。

今回、残念ながら満席だったり時間がかぶってしまって参加できなかったセッションもあったので、あとで読むために現時点で発表者の方が公開されている資料一覧をまとめしました。*3
(あとで JJUG CCC 2018 Spring のページにもリンクが載るかもしれませんが、とりあえず自分の方で調べました)
追記:JJUGGitHub ページで公式な資料一覧が公開されました!
jjug-ccc/slides-articles-2018Spring: JJUG CCC 2018 Spring 登壇資料まとめ

13:30-14:15

15:45-16:30

17:45-18:30

*1:Java は趣味状態

*2:…と書いている割には、人見知りが激しくて積極的に話しかけられていないジレンマ(泣)

*3:発表者のお名前は敬称略とさせていただきました。

トップレベルドメインっていくつあるの?

.com や .jp などのトップレベルドメインドメイン名の一番右側の部分)っていくつあるのか気になったので調べてみました。

トップレベルドメインのリスト

IANA (Internet Assigned Numbers Authority) のページに載っていました。
IANA — Root Zone Database


これによると、現在のトップレベルドメインなんと 1576 個。
(2018年3月23日現在)

内訳

分類 概要 個数
country-code 国別コード .jp / .uk / .eu 312
generic 汎用 .com / .gov / .mil 1235
generic-restricted 汎用(制限付き) .biz / .name / .pro 3
infrastructure インフラ .arpa 1
sponsored スポンサー .aero / .travel / .tel 14
test テスト .test / .テスト 11

なんか generic だけ異様に多いなと思ったら、言語別のドメインが含まれていたり、使われていないものも含まれているようです。
あとは、.hitachi (日立グループ).dell (DELL) のような企業ドメインなんかもここに含まれています。


追加履歴を見てみると、まだまだ増えて行っているようです。
Delegated Strings | ICANN New gTLDs


さすがに全部は覚えられない…。

Java 10 で変わる Java のバージョン表記

Java は、バージョン 10 以降タイムベースリリースに変わりました。
それに合わせて、バージョン表記がまた変わったので概要をまとめました。*1


詳細は JEP 322: Time-Based Release Versioning を参照。

バージョン番号

$FEATURE.$INTERIM.$UPDATE.$PATCH という4つの表記になります。
具体的には、 10.0.1.2 のような表記です。
Java 8 までの Update 〜 という表記はなくなりました)

意味 タイミング 次回予定 内容
$FEATURE 機能リリース 半年ごと 2018年3月 内容にかかわらず半年ごとにリリース
機能追加や互換性のない変更、機能の削除*2を含む
$INTERIM 中間リリース 予定なし - 互換性のあるバグ修正と機能強化*3
(標準APIの変更を含まない)
$UPDATE アップデートリリース 機能リリースの1ヶ月後、およびそれ以降3ヶ月ごと 2018年4月
2018年7月
セキュリティの修正
最新機能のバグ修正
$PATCH パッチリリース 必要時のみ - 重大な問題を解決するための最低限の修正

細かいルール

  • ある桁以降がすべて 0 なら、省略して表記する
    • 例: 11.0.0.0 → 11
    • 例: 11.0.2.0 → 11.0.2
  • $FEATURE, $INTERIM がインクリメントされた場合、それ以降の数字はリセットする
    • 例: 11.0.2 → 11.0.2.1 → 11.1 → 11.1.1
  • バージョン番号以降には、以下を付与する
    • プレリリース識別子(optional)
      • 例: 11.0.2-ea
    • ビルド番号
      • 例: 11.0.2+13
    • LTS などのオプション情報(optional)
      • 例: 11.0.2+13-LTS

プログラム上での取得

これらは、Runtime.Version クラスの各メソッドで取得できます。

jshell> Runtime.version().feature()
$1 ==> 10

jshell> Runtime.version().interim()
$2 ==> 0

jshell> Runtime.version().update()
$3 ==> 0

jshell> Runtime.version().patch()
$4 ==> 0

jshell> Runtime.version().pre()
$6 ==> Optional.empty

jshell> Runtime.version().build()
$5 ==> Optional[46]

jshell> Runtime.version().toString()
$7 ==> "10+46"

あるバージョンよりも新しいか?古いか?を確認するなら、上記で一つづつ比較するよりも compareTo メソッドで比較したほうが確実です。

jshell> Runtime.version().toString()
$1 ==> "10+46"

jshell> Runtime.version().compareTo(Runtime.Version.parse("10.0.1")) > 0
$2 ==> false

jshell> Runtime.version().compareTo(Runtime.Version.parse("9.0.1")) > 0
$3 ==> true

ただ、 Runtime.VersionJava 9 で追加されたクラスです。
もし、Java 8 以前にも対応する必要があるならば、システムプロパティ java.version から取得するしかないのでご注意ください。

jshell> System.getProperty("java.version")
$4 ==> "10"

ちなみに

「リリース日*4」「ベンダーバージョン」がシステムプロパティに追加されました。
Oracle JDK の場合、ベンダーバージョンは当初予定されていた リリース年.リリース月 という表記のままのようです。

jshell> System.getProperty("java.version.date")
$1 ==> "2018-03-20"

jshell> System.getProperty("java.vendor.version")
$2 ==> "18.3"

*1:とはいえ、Java 9 とほぼ一緒

*2:この場合、少なくとも1つ前の機能リリースで予告されます。

*3:JDK1.4.1, JDK1.4.2 のようなケースを想定しているそうです。

*4:正確には GA の日付。なので、Eary Access 版だと未来の日付になります。

Firefox で、アクティブなタブの幅を広くする方法


タブをいくつも開いていると幅が狭くなってしまい、タブのタイトルが読めなくなることがよくあります。
そういうときに、アクティブなタブだけ幅が広くなっていると読めるのになるなーと思ったので、ハックしてみました。

設定方法

  1. about:support を開く*1
  2. プロファイルフォルダーの「フォルダーを開く」をクリック
  3. 新規に chrome フォルダを作成
  4. chrome フォルダの中に、userChrome.cssを作成
  5. userChrome.cssに以下の設定を記載
  6. Firefox を再起動
.tabbrowser-tab[visuallyselected="true"]:not([pinned]) {
    min-width: 225px !important;
}

これで、アクティブなタブだけ幅が広くなります。
もとに戻すときは、userChrome.css を削除するだけでOK。

ホバー時にも幅を広げる設定

非アクティブなタブにマウスカーソルをあてたときにも、タブの幅が広くなるようにもできます。
使いにくく感じるときもありますので、お好みでどうぞ。

  1. userChrome.cssに以下を追記
.tabbrowser-tab:not([visuallyselected="true"]):not([pinned]):hover {
    min-width: 225px !important;
}

注意事項

Firefox のバージョンアップなどで動きがおかしくなったり、バグったりする可能性があります。
そのときは、userChrome.css を削除してください。

*1:ロケーションバー(URLの入力欄)に about:support と入力して Enter を押下