2014年11月3日月曜日

[Java8]メソッド参照

lambda式で定義したい処理内容と全く同じ処理をするメソッドがすでに提供されている場合には、
そのメソッドをメソッド参照という機能を使用してメソッドを渡してあげれば良い。

メソッド参照は、以下のように::演算子でクラス名(オブジェクト名)とメソッド名を連結して使用する。
使用できるパターンは、以下のとおり。

* オブジェクト::instanceメソッド
* クラス名::staticメソッド
* クラス名::instanceメソッド

使用例

System.out.printlnを使用した例は以下のようになる。
list.forEach(System.out::println);

// 上記は、以下と全く同じ
list.forEach(s -> System.out.println(s));

オーバロードされたメソッドがある場合

メソッド参照使用時で、オーバロードされたメソッドが存在していた場合にどのメソッドを呼びだそうとしているかについては、コンパイラがコードの内容から判断しようとする。

例えば、以下の例だとメソッド参照が使用された箇所の関数型インタフェースが受け取る型に対応したメソッドが使用される。

public class Hoge {

    public static void main(String[] args) {
        List strings = Arrays.asList("1", "2", "3");
        strings.forEach(Hoge::output);  // Stringを引数に取るoutputが選択される

        List numbers = Arrays.asList(1, 2, 3);
        numbers.forEach(Hoge::output);  // intを引数に取るoutputが選択される
    }

    public static void output(String s) {
        System.out.println("string");
    }

    public static void output(int i) {
        System.out.println("int");
    }
}

2014年11月2日日曜日

[Java8]Lambda式の形式

ラムダ式は、引数 -> 式本体の形式で記述する。

基本パターン

(String first, String second) -> {
  return Integer.compare(first.length, second.length)
}

型推論可能な場合は、引数の型を省略出来る

左辺の総称型などから推論可能な場合などに型推論される。
(first, second) -> {
  return Integer.compare(first.length, second.length)
}

型推論された引数を一つだけ保つ場合には、カッコも省略可能

Arrays.asList(1, 2, 3, 4, 5).forEach(n -> System.out.println(n));

アノテーションなど

メソッドの引数と同じように、、アノテーションやfinal修飾子をつけることも可能
(final String first, final String second) -> {
  return Integer.compare(first.length, second.length)
}

戻り値について

lambdaの戻り値は明示しない。常に文脈から型が判断される。
以下の例だとintが期待されているところで使用できる。

※分岐などで結果を返したり返さなかったりするようなlambda式は不正となる。(コンパイルエラー)
(final String first, final String second) -> {
  return Integer.compare(first.length, second.length)
}

2014年10月22日水曜日

Java8のFunctionalInterfaceアノテーション

FunctionalInterfaceは、関数型インタフェースであることを示すために使用するアノテーション。

基本的に、関数型インタフェースの要件(インタフェースで抽象メソッドは1つなど・・・)を満たしていれば良いが、
FunctionalInterfaceアノテーションを付加するとコンパイル時に関数型インタフェースの要件を満たしていない場合コンパイルエラーとしてくれる。
また、このインタフェースが関数型インタフェースであることが、明確なので関数型インタフェースにはこのアノテーションを付加するとよい。

例えば、以下の様なインタフェース定義は関数型インタフェースの要件を満たさないためコンパイルエラーとなる

@FunctionalInterface
interface Hoge {
    void hoge();
    void fuga();
}

エラー内容としては以下の様なものが出力される。
Error:(1, 1) java: 予期しない@FunctionalInterface注釈
  Hogeは機能インタフェースではありません
    インタフェース Hogeで複数のオーバーライドしない抽象メソッドが見つかりました

2014年10月5日日曜日

[jQuery]first-of-typeセレクタ

バージョン1.9から追加されたセレクタ。

親要素内で、セレクタで指定した要素が最初に出現する要素が選択される。

この例だと、div要素内で最初に出現するspanタグが選択される。
(hogeとあいうえおのspanタグ)
<div>
  <span>hgoe</span>
  <span>fuga</span>
</div>
<div>
  <span>あいうえお</span>
  <span>かきくけこ</span>
  <span>さしすせそ</span>
</div>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
  $("span:first-of-type").css({
    color: 'red'
  });

</script>

表示結果

選択された最初のspanタグにスタイルが設定されているのがわかる。

※first-of-typeと逆のlast-of-typeセレクタもある。

2014年7月11日金曜日

Activiti-explorerをtomcatにデプロイ

1. activitiをダウンロード

http://activiti.org/download.html からActivitiをダウンロードする。
ダウンロードされたファイルは任意のディレクトリに解凍しておく。

2. Tomcatをダウンロード

http://tomcat.apache.org/download-80.cgiからTomcatをダウンロードする。
ダウンロードされたファイルは任意のディレクトリに解凍しておく。

3.Activiti-ExplorerをTomcatにデプロイする。

ダウンロードしたAcitivitiを解凍したディレクトリ内の「wars/activiti-explorer.war」を、
Tomcatを解凍したディレクトリの「webapps」にコピーする。

4.Tomcatを起動する。

Tomcatを解凍したディレクトリの「bin/startup.sh」を実行し、Tomcatを起動する。

5.画面を開く

http://localhost:8080/activiti-explorer/ にアクセスする。
以下の様な画面が開けば、デプロイは成功しています。


6.ログインの実行

アカウントは「http://www.activiti.org/userguide/#deploymentWithExplorer」の「Activiti setup」の章に記述されています。

まずは、デプロイして実行出来るところまで。
UI気にしなければこのまま、使えるのかな?もうちょっと調べてみないと。

2014年4月29日火曜日

[AngularJS]ng-initを使用して初期値の設定

ng-initディレクティブを使用して、初期値の設定が出来る。

コード

<!DOCTYPE html>
<html>
<head lang="en">
  <meta charset="UTF-8">
  <title>ng-init</title>
  <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.15/angular.min.js"></script>
</head>
<body ng-app>
<div ng-init="hello = 'Hello'" >
  {{hello}} World!!<br/>

  <label>入力欄
    <input type="text" ng-model="hello">
  </label>
</div>
</body>
</html>

実行結果

2014年4月2日水曜日

[html5]canvas上に画像を配置

context#drawImageを使用してcanvas上に画像を配置することができる。

以下のように3種類のdrawImageを用途によって使い分ける。
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>canvasに画像を配置</title>
  <style>
    #mycanvas {
      outline: blue 1px solid;
    }
  </style>
</head>
<body>
<!-- canvas上に配置する予定の画像を非表示で用意する -->
<div style="display: none">
  <img src="hoge.png" alt="example" id="myimage" width="592" height="59"/>
</div>
<canvas id="mycanvas" width="800" height="350">
</canvas>
<script>
  !function () {
    var canvas = document.getElementById('mycanvas'),
        ctx;

    if (!canvas.getContext) {
      return;
    }

    ctx = canvas.getContext('2d');
    window.addEventListener('load', function() {
      var image = document.getElementById('myimage');
      // 左上のポジション指定
      ctx.drawImage(image, 10, 10);
      // ポジションと幅、高さ指定
      ctx.drawImage(image,
          10, 90,   // 左上のポジション
          102, 49); // 幅と高さ
      
      // 元画像の描画範囲(切り取り範囲)と幅と高さを指定
      ctx.drawImage(image,
          60, 30,   // 切り取り開始位置(左上の開始位置)
          25, 40,   // 切り取る幅と高さ
          10, 180,  // 画像を配置する左上のポジション
          25, 40);  // 画像の幅と高さ
    });
  }();
</script>
</body>
</html>