re:annkara

日々学んだことを書き留めておく。

ジェネリクス入門

Javaジェネリクスについて、自分なりにまとめておきたいと思う。
謝り等ありましたらご指摘いただけると幸いです。

ジェネリクスが使えると何が良いか??

いきなりだけど、ジェネリクスのメリットを考えて見る。
例えば、オブジェクトを保持する適当なクラスは以下のとおり。

public class Box {

    private Object obj;

    public void add(Object arg){
        this.obj = arg;
    }

    public Object get(){
        return this.obj;
    }
}

このBoxクラスをインスタンス化する場合、Objectクラスなのであらゆるオブジェクトを扱うことができる。
あらゆるオブジェクトを使える一方で、StringやInteger、もしくはユーザ定義したクラスのオブジェクトなどを扱う際には、 getメソッドを呼び出す際に、必ずキャストしなければならない。

Box box = new Box();  
box.add("文字列を格納");  
String str = (String) box.get();  

このキャストを忘れてしまうと、実行時にClassCastExceptionが発生してしまう。
ここで問題となるのは以下の2点になる。
1. プログラマにキャストを強制する。 → キャスト忘れちゃうかも。
2. 実行時されるまでこのクラスを利用した処理が成功するかわからない。 → コンパイル時にわかった方がよくない??

だからといって、文字列を扱うStringBoxクラス、Integerを扱うIntegerBoxクラス、ユーザ型を扱うUserBoxクラス、、、、などなどと、 各オブジェクトに対応するクラスを作成するのはなかなかに辛さがある。
ここで、任意の型を扱うBoxクラスというのを定義できたらいいんじゃない??というわけででてきたのが、ジェネリクスである。
上のBoxクラスをジェネリクス型に置き換えると以下のとおり。

public class Box<E> {

    private E obj;

    public void add(E arg){
        this.obj = arg;
    }

    public E get(){
        return this.obj;
    }
}

クラス宣言に<E>を付け加えて、Objectと宣言していたところを単にEで置き換えただけだけど、こうするだけでキャスト不要で、 コンパイル時に型チェックが入る任意のBoxクラスを作ることができた。
ジェネリクスがあれば、キャスト処理も特有のクラス定義も不要で、安全で柔軟な型を定義することができる,というのが個人的にはメリットだと考えている。

ジェネリクス周りの用語の整理

<E>の表記が登場したので、ここでジェネリクス周りの用語を整理しようと思う。
用語の一覧はEffective Javaの項目23から抜粋。

  1. ジェネリクス
    Box<T>

  2. 仮型パラメータ、仮型変数
    T
    通常大文字1文字で表現されることが多い。名前自体はなんでも良いが、TはType、KはKeyを表すなどの慣習は存在する。

  3. パラメータ化された型、ジェネリクス型の呼び出し
    Box<String>
    型パラメータに具体的な型 (Stringなど)を代入することで、その型の役割( どの型を扱うことができるか)を決める程度に理解している。

  4. 実型パラメータ、実型変数
    String など
    仮型パラメータに代入される具体的な型。

  5. raw型
    Box
    ジェネリクス型を使用しない型のこと。特段の事情がない限り、raw型を使うべきではない。

ワイルドカードや境界型パラメータなど、まだ出てきていない概念については後述しようと思います。
思いの外長くなってしまったので、一旦ここまでで。

はじめてのJJUG CCC #jjug_ccc

生まれて初めてのカンファレンスということで、

JJUG CCC 2016 Fall

に参加してきました。 当日の登壇者の方々の資料は以下にあるそうです。

GitHub - jjug-ccc/slides-articles-2016fall: JJUG CCC 2016 Fallの発表資料およびブログ記事まとめ

参加したセッション

当日は想像以上に参加者の方が多く、会場の雰囲気にのまれてあまりメモったりできなかったのですが、 今振り返ってみると、今後の学びのヒントがいろいろと得られたと思うので、そのことについて書いていきたいと思います。 メモ書きなのでだいぶ粗いです 汗

SIerもはじめる、わたしたちのDevOps

@syobochimさん@_Dr_ASAさんのセッション。 @syobochimさんのセッションではDevOpsの説明から、業務への適用までのお話をされていました。 仮説→検証→実践→振り返りのサイクルを回しながら開発していくのは、成果が短時間で目に見えて楽しいだろうなぁと思ったり、その一方で、お客さんがDevOpsという考え方をちゃんと理解していたり、適用する範囲も全て適用できるわけではなさそうかなとも思いました。*1 技術的な面では、enkanfalchion-containerを利用して、デプロイ時間の短縮や無停止デプロイの実現など、だいぶ興味深いことをされていたので、ここらへんのお話は自分でも深めていきたいと思いました。

かわって@_Dr_ASAさんさんのセッションではDockerの話題を中心に、変化に強いシステムであったり、システム構築するにあたり組織としてのあり方やエンジニア個人としてのこれからのあり方をお話されていました。特にエンジニア個人としてのあり方には非常に共感するところがあり、様々な分野の知識を自分で習得していく必要があるという部分は日々思っていることなんですけど、あまり実践できずということもあり、頑張っていきたいなぁと(小学生並みの感想)。

Javaの型システム再入門 〜オブジェクト指向からジェネリクスまで〜

@nagiseさんのセッション。 仕事ではなんとなく使っていて、チュートリアルを見てもイマイチ理解できなかったので参加させていただきました。 硬派な内容だったので、途中から理解がついていけなくなってしまったあたり、まだまだなのだなと実感しました。 ジェネリクス周りはまた別途自分で調べてみて内容をまとめていきたいと思います。

JVMのトラブル解決のためにやったこと~メモリー/スレッド

@bloody_snowさんのセッション。 JVM周りのメモリ管理について知りたくて参加しました。 立ち見の大盛況だったのですが、Twitterばかり見てしまっていてあまり発表に集中できなかった 汗 Twitterから流れてきたここが参考になるそう。 JVMのツール周りは全く触ったことがないので、機会があれば触ってみたい。

JVM言語とJava、切っても切れないその関係

@yy_yankさんのセッション。 JavaJVM言語の歴史や関係などをゆるふわなテンションで語られてて非常に面白い方でした。 JavaJVM言語もお互い良い所、悪い所あってお互い切磋琢磨して成長していこうよみたいなスタンスは非常に好ましいなぁ。

まとめ

初めのjjug cccだったんですが、学ぶことが非常に多くて刺激的なカンファレンスでした。 聞くだけじゃ自分の身につかないと思うので、今回聞いたことや、他の登壇者の方々のスライドを見て、自分の中で解釈する必要があるなと、 この記事を書いていて再度思いました。

最後に、登壇者の方々、ボランティアスタッフの方々、関係者の方々、素敵なカンファレンスありがとうございました!! また、春にでも参加したいと思います!!

*1:弊社だと、新しい保険商品を開発する際には、既存システムが大きすぎてアジャイル的に開発できない場合などかなぁ

Web APIを利用して簡単な英和辞書機能を実装してみた。

プログラミングの学習をしていると、どうしても英文を読まないといけないときがあって、 分からない単語にぶつかる度に検索するのが面倒だった。
なので、あらかじめ英文を用意してそこに含まれる単語の訳を一覧にできないかと思ってちょっと作ってみた。
結果から言うと、その機能は断念した。

#! /usr/bin/python
# -*- coding: utf-8 -*-

import urllib2, json

def translate(phrase):

    from_ = "en"
    dest_ = "ja"

    api_url = \
      "https://glosbe.com/gapi/translate?from={0}&dest={1}&format=json&phrase={2}&pretty=true".format(from_, dest_, phrase)

    res = urllib2.urlopen(api_url)

    # この段階ではまだ文字列形式なので、
    # json.loadsメソッドで辞書型へと変換する。
    js_data = res.read()
    js_dict = json.loads(js_data)

    result = {}
    temp = []
    tuc = js_dict['tuc']
    for i in range(len(tuc)):
        try:
            temp.append(js_dict['tuc'][i]['phrase']['text'])
        except KeyError:
            continue

    result = {phrase:temp}
    return result

if __name__ == "__main__":

    result = translate("apple")

    for _, v in result.items():
        for val in v:
            print val.encode('utf-8')

jsonのパースのとことか、検索単語を直で扱っているあたりとか、いろいろあれだけどとりあえず訳はでる。

本当だったら、入力された英文を単語毎にまとめて訳を出力しようと思っていたのだけど、 Web APIを利用させてもらっている手前一単語ずつアクセスするのが憚られたので、それは断念した。
予め自分の知らなそうな単語だけをピックアップして、その単語だけ検索かけるみたいなこととかできればなと。
もしくは、時間を空けて断続的なアクセスをするようにするとか。
そこら辺の作法的な部分も抑えておかないと。

参考にさせていただいたサイト
英単語の日本語訳をプログラム内やターミナル内で取得する - roombaの日記

利用させて頂いたAPI

Online dictionary

glosbe.com

本当に簡単な機能だけど、Web APIの使い方や(めたんこ下手だけど)jsonのパースとか Pythonの構文を学ぶだけじゃやらないようなことを学べて楽しかった。
合わせて、Pythonエンジニア養成読本でbottleを使ったWebアプリケーションの作成もやってみたので、 ちょっとずつだけど、いろいろなことを出来るようになってきた気がする。
それでもまだまだ全然知らないことばかりだし、全然へっぽこだけど。

年明け前からずっといろいろとやってきたけど、やっぱり継続することが大事なんだと思う。
毎日ほんの少しずつでも、何かしらをやってみて、それが知らないうちに自分の知識や経験になっているのだと。

へっぽこだけどへっぽこじゃなくなるために、これからも続けていく所存であります。

過ぎた欲は身を滅ぼす。

文庫版が発売されてからだいぶ経ってしまったけど、真山仁さんの「グリード」をやっと読んだ。

強欲は善、ではあるが過ぎた欲は身を滅ぼす、というのが率直な感想。

サブプライムローン全盛のアメリカが当時、実際にどんな状況にあったのかわからないけど、
渦中にいた人たちはずっとその好況が続くんだろうなぁと思っていたんじゃないか。

その十数年前には、日本が経験したように。

人間は自分の信じたいものしか信じないし、聞きたくないことは聞かないし、
見たくないものはきっと見ない生き物なんだろうけど、
ちゃんと現実を見据えられる人がいないと駄目なんだろうね。
現実を見据えてちゃんと行動できる人。

ハゲタカシリーズを読むたびにこういう目まぐるしい状況が今現在進行中であることを 思い知らされるし、いつ自分がその渦中に巻き込まれるか分からないことを実感させられる。

そんな状況にいても楽しんで乗り越えられたらなと思う。

ハゲタカ4 グリード(上) (講談社文庫) | 真山 仁 | 本 | Amazon.co.jp

ハゲタカ4 グリード(下) (講談社文庫) | 真山 仁 | 本 | Amazon.co.jp

近況

最近は業務が忙しかったり、体調を崩しがち。

やはり健康第一じゃないとだめだ。

初めてのPythonもようやくクラスのとこまで目を通した。

ただ、関数あたりからメモる量が格段に増えてブログに載せきれないというか途中からメモを断念してしまった。

まぁ、また再読すると思うからそのときに再度メモってみよう。

最近やっとPythonのちょっと深いところまで理解できてきたので、
そろそろ何か実践的なことをしたいなぁと。

そう思ってbottleのチュートリアルやってみた。

Djangoと違って軽量フレームワークだから、さくさくと進んで、 ローカル環境だけど簡単なto doアプリケーションの作成ができた。

bottleの良いところは公式ドキュメントの英語が簡単でわりとさくさくと読めるとこと、
bottle自体が1つのモジュールで構成されているから、ソースもわりかしと読めるとこかな。

まぁ、全然理解はできてないんだけど。

そんな感じでがしがしと何かを作っていきたいと思うこのごろ。

初めてのPython再挑戦2

初めてのPythonのメモがき。
今日はステートメントの部分のポイントをまとめる。

条件の評価式の際には()は任意

a = []
in not a:
    print a #空のリストが表示

代入ステートメントについて

代入は変数とオブジェクトリファレンスを結びつける操作のこと。 変数はオブジェクトリファレンスを保持するのみであり、 型情報はあくまでオブジェクト側で保持されていることに注意。

形式
  • シーケンス代入
a, b, c, d = "spam"
print a # 's'と表示
print b # 'p'と表示

左辺の変数の数と、右辺のシーケンスの要素数が一致しないとエラーなる。 そういう場合は、スライシングを利用すると良い。

str = "spam"
a, b, c = str[0], str[1], str[2:]
print c # 'am'と表示
  • マルチターゲット代入

複数の変数に同一のオブジェクトリファレンスを保持させることができる。

a = b = [] # a b ともに空のリストの共通リファレンスを保持する
a.append(1)
print a, b # ([1],[1])と表示

b.append(2)
print a, b # ([1, 2], [1, 2])と表示

いわゆる、+=や/=なやつ。
演算対象が可変オブジェクトである場合、ちょっと変わった振る舞いをする。

L = [1,2]
L = L + [3] # リストの連結 このとき新しいリストオブジェクトが生成され代入される
L = L.append(4) # appendを利用すれば元のオブジェクトの上書きをする

新しいオブジェクトを生成するか、上書きをするのか挙動が変化する。 このとき、拡張代入ステートメントを使用すれば、処理系が自動で実行速度で高率な方を採用するため、 あまり考えなくてよい。

printステートメント

オブジェクトのデータをテキストに変換して標準出力ステートメントに書き込むステートメント

標準出力の変更

sys.stdoutにwriteオブジェクトを備えたオブジェクトを代入すれば、printステートメントが リダイレクトされる。

>>でもリダイレクトは可能であるが、これは一度キリなので、何度もリダイレクトしたい場合は sys.stdoutを弄った方がよい。

forループ

forステートメントを使用しないループ処理の書き方もある。 処理対象のオブジェクトをiter()に渡すと、イテレータオブジェクトを返す。 そのオブジェクトに対して、nextメソッドを実行すると、要素を返してくれる。

L = [1,2,3]
I = iter(L) # 反復処理に対応したオブジェクトを生成

I.next() # 1を表示 要素がつきるとStopIteretion例外を発生させる

リスト内包表記

メリットとして、コードが簡潔になる。 また、処理速度もforループを使用したときよりも高速になる。 これは反復処理がPythonのコードレベルではなく、インタプリタの内部で Cのコードレベルで実行されるから。 デメリットとして、いくらでも拡張することができるため、複雑な処理を記述すると可読性が落ちてしまう点。