guavaでコレクション

guava09もリリースされたので、少しCollections2の使い方でも書いてみる。

com.google.common.collect.Collections2#filterの使い方

        final String Aaa = "A"; // #apply内で使用するためfinalにする
        List<SomeType> srcBeans = someMethod();

        Predicate<SomeType> predicate = new Predicate<SomeType>() {
            @Override
            public boolean apply(SomeType bean) {
                // Fieldが"A"の場合コレクションから外す
                if(bean.getField().equals(Aaa)){
                    return false;
                }
                return true;
            }
        };
        // destBeansは、Field="A"を満たす要素は除外されている
        Collection<SomeType> destBeans = Collections2.filter(srcBeanss, predicate);

これだけみると便利なのか?って思うかもしれませんが、
Predicateクラスのインスタンスを引数で受け取ったり、Predicate作成用にファクトリクラスを作ったりしたら便利そうじゃありませんか?(^^

ちなみに、PredicatesクラスのスタティックメソッドでPredicate同士の論理和や論理積などの論理演算が使えます。
http://guava-libraries.googlecode.com/svn/tags/release09/javadoc/com/google/common/collect/Collections2.html


では次、Predicateを作るメソッドをつくって、
フィルターするときの、"条件の作成"と"条件の適用"を明確に分けられるので、読みやすくなります。

com.google.common.collect.Collections2#filterの使い方 (Predicateを別途作成する)

import java.util.Collection;
import java.util.List;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;

public class Sample01 {
    public static void main(String[] args) {

        List<String> srcBeans = Lists.newArrayList("A","B","C","D","E","F","G");

        Collection<String> destBeans = Collections2.filter(srcBeans, notB());

        for(String bean : destBeans){
            System.out.println(bean);
        }
    }
    /**
     * B以外に合致する条件を返却します。
     * @return B以外に合致する条件
     */
    public static Predicate<String> notB(){
        return new Predicate<String>(){
            @Override
            public boolean apply(String arg) {
                return "B".equals(arg) ? false : true;
            };
        };
    }
}

【実行結果】

A
C
D
E
F
G


では次、複数のPredicateのいずれの条件にも合致する要素(論理積)を取り出す例です。

com.google.common.collect.Collections2#filterの使い方 (Predicateの論理演算(論理積))

論理積の場合、Predicates#andを使用します。

import java.util.Collection;
import java.util.List;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
public class Sample02 {
    public static void main(String[] args) {
        List<String> srcBeans = Lists.newArrayList("A","B","C","D","E","F","G");
        Collection<String> destBeans = Collections2.filter(srcBeans, Predicates.and(notB(), notC()));

        for(String bean : destBeans){
            System.out.println(bean);
        }
    }
    /**
     * B以外に合致する条件を返却します。
     * @return B以外に合致する条件
     */
    public static Predicate<String> notB(){
        return new Predicate<String>(){
            @Override
            public boolean apply(String arg) {
                return "B".equals(arg) ? false : true;
            };
        };
    }
    /**
     * C以外に合致する条件を返却します。
     * @return B以外に合致する条件
     */
    public static Predicate<String> notC(){
        return new Predicate<String>(){
            @Override
            public boolean apply(String arg) {
                return "C".equals(arg) ? false : true;
            };
        };
    }
}

【実行結果】

A
D
E
F
G


では次、複数のPredicateのうち、いずれかひとつに合致する要素(論理和)を取り出す例です。

com.google.common.collect.Collections2#filterの使い方 (Predicateの論理演算(論理和))

論理和の場合、Predicates.orを使用します。

import java.util.Collection;
import java.util.List;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;
public class Sample02 {
    public static void main(String[] args) {
        List<String> srcBeans = Lists.newArrayList("A","B","C","D","E","F","G");
        Collection<String> destBeans = Collections2.filter(srcBeans, Predicates.or(notB(), notC()));

        for(String bean : destBeans){
            System.out.println(bean);
        }
    }
    /**
     * B以外に合致する条件を返却します。
     * @return B以外に合致する条件
     */
    public static Predicate<String> notB(){
        return new Predicate<String>(){
            @Override
            public boolean apply(String arg) {
                return "B".equals(arg) ? false : true;
            };
        };
    }
    /**
     * C以外に合致する条件を返却します。
     * @return B以外に合致する条件
     */
    public static Predicate<String> notC(){
        return new Predicate<String>(){
            @Override
            public boolean apply(String arg) {
                return "C".equals(arg) ? false : true;
            };
        };
    }
}

【実行結果】

A
B
C
D
E
F
G

Guice 3.0がリリースされています。

ついにGuice3.0がリリースされました。
RC3まで出たので不具合は少ないはず(?)。最近の更新をみるとwikiを充実させていたのでしょうかね。
http://code.google.com/docreader/#p=google-guice&s=google-guice&t=Guice30

Guice2.0との差異も公表されています。
http://google-guice.googlecode.com/svn/trunk/latest-api-diffs/3.0/changes.html

Guice3.0がやっとセントラルレポジトリにアップされた

Guice3.0がRC2からセントラルレポジトリに登録された模様。
早速、pom.xmlを変更した。(いままでGuice 2.0だった)

        <!--  GUICE -->
        <dependency>
            <groupId>com.google.inject</groupId>
            <artifactId>guice</artifactId>
            <version>3.0-rc2</version>
        </dependency>

そして、コンパイル。

[INFO]    task-segment: [install]
[INFO] ------------------------------------------------------------------------
[INFO] [resources:resources]
[INFO] Using default encoding to copy filtered resources.
Downloading: http://wiquery.googlecode.com/svn/repo//com/google/inject/guice/3.0-rc2/guice-3.0-rc2.pom
Downloading: http://repository.jboss.org/maven2/com/google/inject/guice/3.0-rc2/guice-3.0-rc2.pom
Downloading: http://wicketstuff.org/maven/repository/com/google/inject/guice/3.0-rc2/guice-3.0-rc2.pom
Downloading: http://wicketstuff.org/maven/repository/com/google/inject/guice/3.0-rc2/guice-3.0-rc2.pom
Downloading: http://repo1.maven.org/maven2/com/google/inject/guice/3.0-rc2/guice-3.0-rc2.pom
Downloading: http://wiquery.googlecode.com/svn/repo//com/google/inject/guice-parent/3.0-rc2/guice-parent-3.0-rc2.pom
Downloading: http://repository.jboss.org/maven2/com/google/inject/guice-parent/3.0-rc2/guice-parent-3.0-rc2.pom
Downloading: http://wicketstuff.org/maven/repository/com/google/inject/guice-parent/3.0-rc2/guice-parent-3.0-rc2.pom
Downloading: http://wicketstuff.org/maven/repository/com/google/inject/guice-parent/3.0-rc2/guice-parent-3.0-rc2.pom
Downloading: http://repo1.maven.org/maven2/com/google/inject/guice-parent/3.0-rc2/guice-parent-3.0-rc2.pom
Downloading: http://wiquery.googlecode.com/svn/repo//javax/inject/javax.inject/1/javax.inject-1.pom
Downloading: http://repository.jboss.org/maven2/javax/inject/javax.inject/1/javax.inject-1.pom
Downloading: http://wicketstuff.org/maven/repository/javax/inject/javax.inject/1/javax.inject-1.pom
Downloading: http://wicketstuff.org/maven/repository/javax/inject/javax.inject/1/javax.inject-1.pom
Downloading: http://repo1.maven.org/maven2/javax/inject/javax.inject/1/javax.inject-1.pom
Downloading: http://wiquery.googlecode.com/svn/repo//com/google/inject/guice/3.0-rc2/guice-3.0-rc2.jar
Downloading: http://repository.jboss.org/maven2/com/google/inject/guice/3.0-rc2/guice-3.0-rc2.jar
Downloading: http://wicketstuff.org/maven/repository/com/google/inject/guice/3.0-rc2/guice-3.0-rc2.jar
Downloading: http://wicketstuff.org/maven/repository/com/google/inject/guice/3.0-rc2/guice-3.0-rc2.jar
Downloading: http://repo1.maven.org/maven2/com/google/inject/guice/3.0-rc2/guice-3.0-rc2.jar
Downloading: http://wiquery.googlecode.com/svn/repo//javax/inject/javax.inject/1/javax.inject-1.jar
Downloading: http://repository.jboss.org/maven2/javax/inject/javax.inject/1/javax.inject-1.jar
Downloading: http://wicketstuff.org/maven/repository/javax/inject/javax.inject/1/javax.inject-1.jar
Downloading: http://wicketstuff.org/maven/repository/javax/inject/javax.inject/1/javax.inject-1.jar
Downloading: http://repo1.maven.org/maven2/javax/inject/javax.inject/1/javax.inject-1.jar
[INFO] [compiler:compile]

ちゃんとダウンロードされました

SAMタイプ

SAMタイプのSAMとは、Single Abstract Method の略です。
直訳すればなんとなくイメージはつかめます。「単一」「抽象」「メソッド」。
つまり、SAMタイプとは、
一つの抽象メソッドだけで構成されたクラスもしくはインタフェース
のことです。
Comparatorのcompare()などがSAMタイプですね。
SAMタイプのメリットは分かりやすさだと自分では思っています。「Comparator」なら、あぁ、「compare()」できるのね。って一目了然です。また関数オブジェクト的に使ったりします。

Javaには、匿名メソッドがないので、SAMタイプのインタフェースやクラスをつかって疑似クロージャを作ったりするのが有名ですね。

interface Invoker<T>{
    public void invoke(T arg);
}

こんなインタフェースを定義しておいて、

  Dao dao = DaoFactory.createDao(User.class);

  final InBean inBean = someMethod();
  Invoker invoker = new Invoke<InBean>(){
      @Override
      public void invoke(inBean){
          dao.insert(inBean);
      }
  }

こんな使い方をします。(コードはすごくテキトー。)

Guice 3.0

Guice 3.0RCを試してみた。

注入するオブジェクトにアノテーションをつけなくてもよくなったとのこと。今度試してみよう。

2.0のときと違って、javax.inject.jarも一緒にクラスパスにいれないと動かなくなった。

ListsやMapsは消えていた。Guavaを使えってことかな。

guava R06 リリース

ざっとみたところ、InternetDomainName.java、InetAddresses.javaのバグが修正されている。
GitHub - google/guava: Google core libraries for Java


それからアノテーションを指定していなかったところにちゃんと(?)指定していたりする。
(@Nullableをしていしていたりね。)

あとFunctions#applyとかStrings#padStartとかStrings#padEndとかStrings#repeatとかがPreconditions#checkNotNullを
呼ぶようになっていた。