4473


どちらもリストを変換できますが、どう違うのかを共有します。まずは書き方。

# 1. `Lists.transform()`の場合：

[code]

    List<String> list = Lists.newArrayList("aaa", "bbb", "ccc");
    List<String> newList = Lists.transform(list, new Function<String, String>() {
        public String apply(String input) {
            System.out.println("transform -> " + input);
            return input + "_add";
        }
    });
    
[/code]

# 2. `FluentIterable.from().transform().toList()`の場合：

[code]

    List<String> list = Lists.newArrayList("aaa", "bbb", "ccc");
    List<String> newList = FluentIterable.from(list).transform(new Function<String, String>() {
        public String apply(String input) {
            System.out.println("transform -> " + input);
            return input + "_add";
        }
    }).toList();
    
[/code]


CC BY-SA 3.0
2015-01-13T03:49:41.677
4472
2015-01-14T01:09:37.320
2015-01-13T05:35:19.940
7214
7214
question
java guava
Guavaで、Lists.transform()とFluentIterable.from().transform().toList()の違いは？


# 確認コード

[code]

    System.out.println(list.toString());
    System.out.println(newList.toString());
    list.add("ddd");
    System.out.println(list.toString());
    System.out.println(newList.toString());
    
[/code]

## 1. `Lists.transform()`の場合：

`Function`で定義された関数は遅延評価され、参照される際に変換関数が呼ばれます。よって、元のリストを変更した場合、その変更が
**変換先のリストにも反映されます** 。

実行結果：

[code]

    [aaa, bbb, ccc]
        transform -> aaa
        transform -> bbb
        transform -> ccc
    [aaa_add, bbb_add, ccc_add]
    [aaa, bbb, ccc, ddd]
        transform -> aaa
        transform -> bbb
        transform -> ccc
        transform -> ddd
    [aaa_add, bbb_add, ccc_add, ddd_add]
    
[/code]

## 2. `FluentIterable.from().transform().toList()`の場合：

リストがコピーされるため、元のリストを変更しても、その変更が **変更先のリストに反映されません** 。

実行結果：

[code]

    [aaa, bbb, ccc]
        transform -> aaa
        transform -> bbb
        transform -> ccc
    [aaa_add, bbb_add, ccc_add]
    [aaa, bbb, ccc, ddd]
    [aaa_add, bbb_add, ccc_add]
    
[/code]

# どちらを使うべきか

変更先のリストが変更元のリストと同じ要素で必要な場合は`Lists.transform()`を使用し、変更元のリストと同じである必要がない、一度きりの変換のみでよければ`FluentIterable.from().transform().toList()`を使用するほうが良いでしょう。

上記を理解していれば`Lists.transform()`を必要に応じて使用してよいと思いますが、なんでもかんでも`Lists.transform()`を使用していると、参照の度に変換関数が呼ばれ、その変換処理が重たい場合、思わぬボトルネックとなりますので注意が必要です。  
`Guava`をよく知らない技術者がいる場合、混乱の元になりますので明示的に使い分ける方が良いと思います。

なお、`FluentIterable.from().transform()`で`FluentIterable`型のリストを取得した場合、
**`Lists.transform()`と同様の振る舞いをします**。リストのコピーにしたければ必ず`toList()`で受け取る必要があります。

参考URL：  
[guava - difference between Lists.transform(…, …) and
FluentIterable.from(…).transform(…)](https://stackoverflow.com/questions/25897767/guava-
difference-between-lists-transform-and-fluentiterable-from)  
[guavaライブラリのLists.transformを使う際の注意点](http://qiita.com/yuichielectric/items/2f5dff4e1df896c1ae24)


CC BY-SA 3.0
2015-01-13T03:49:41.677
4473
2015-01-14T01:09:37.320
2017-05-23T12:38:56.083
-1
7214
4472
answer