Lists.transformメソッドで使用されるピット-ピットの概要16(週に1回更新)

創造を続け、成長を加速させましょう!「ナゲッツデイリーニュープラン・6月アップデートチャレンジ」に参加して6日目です。クリックしてイベントの詳細をご覧ください。

バックグラウンド

googleが提供するLists.transformメソッドを使用して、特定のロジックを介してエンティティクラスのリストを別のエンティティクラスのリストに変換できます。たとえば、次の例では、文字列のリストを整数のリストに変換します。

例:List<String>AはList<Integer>Bに変換されます。示されているように

public static void main(String[] args) {
    List<String> tests = Stream.of("haha", "hehe").collect(Collectors.toList());
    List<Integer> integers = Lists.transform(tests, t -> {
        return t;
    });
}
复制代码

質問

コレクションIDは、Lists.transformメソッドに値を追加しますが、最終的には追加されません。

public static void main(String[] args) {
    List<Long> ids=new ArrayList<>();
    List<Integer> tests = Stream.of("123", "321").collect(Collectors.toList());
    List<Integer> integers = Lists.transform(tests, t -> {
        ids.add(1L);
        return Integer.parseInt(t);
     });
    System.out.println("结果:"+JSON.toJSON(ids));
}
复制代码

印刷結果は次のとおりです。

image.png

ブレークポイントをヒットして、実行されるかどうかを確認しましょう

最初のブレークポイントが入っておらず、2番目のブレークポイントが直接入っていることがわかります。image.png

理由

上記の現象から、

  • Lists.transformメソッドは、実際にはすぐに変換を実行しませんが、変換を遅らせます。
  • ソースコードをクエリすると、Lists.transformを実行した直後にsourceListに値が割り当てられず、イテレータを書き換えるTransformingRandomAccessListタイプに変換されるだけで、userFormListを繰り返すたびに、関数が割り当てのために呼び出されます。
  • また、foreachで渡された関数が一度実行されるたびに、関数内のメソッドがより効率的になる必要があります。したがって、不適切に使用すると問題が発生します。原則はサブリストに少し似ており、実際には内部クラスを返します。

image.png

image.png

解決

最初の方法:ラッパークラスを使用して、返された内部オブジェクトをラップします

  public static void main(String[] args) {
        List<Long> ids = new ArrayList<>();
        List<String> tests = Stream.of("123", "321").collect(Collectors.toList());
//        List<Integer> integers = Lists.transform(tests, t -> {
//            ids.add(1L);
//            return Integer.parseInt(t);
//        });
        List<Integer> integers = new ArrayList<>(Lists.transform(tests, t -> {
            ids.add(1L);
            return Integer.parseInt(t);
        }));

        System.out.println("结果:" + JSON.toJSON(ids));
    }
复制代码

結果:

image.png

2番目の方法:グーグルが提供するメソッドなしで単純な変換を実装する

public static <F, T> List<T> transformList(List<F> fromList, Function<F, T> fuction) {
    if (fromList == null) {
        return new ArrayList<>();
    }
    List<T> lists = new ArrayList<>();
    for (F from : fromList) {
        lists.add(fuction.apply(from));
    }
    return lists;
}
复制代码

使用法をテストするためのメインメソッドを記述します。

  public static void main(String[] args) {
        List<Long> ids = new ArrayList<>();
        List<String> tests = Stream.of("123", "321").collect(Collectors.toList());
//        List<Integer> integers = Lists.transform(tests, t -> {
//            ids.add(1L);
//            return Integer.parseInt(t);
//        });
//        List<Integer> integers = new ArrayList<>(Lists.transform(tests, t -> {
//            ids.add(1L);
//            return Integer.parseInt(t);
//        }));
        List<Tet2> tet2List=new ArrayList<>();
        Tet2 tet2=new Tet2(1L,"haha");
        tet2List.add(tet2);
        List<Tet1> tet1List = transformList(tet2List, m -> {
            Tet1 tet1 = new Tet1();
            tet1.setId(m.getId());
            tet1.setName(m.getName());
            return tet1;
        });
        System.out.println("结果:" + JSON.toJSON(tet1List));
    }
复制代码

印刷結果は次のとおりです。

image.png

要約する

サードパーティのオープンソースフレームワークを使用する場合は、サードパーティのフレームワークの使用における隠れた落とし穴を防ぐための原則を必ず理解してください。

おすすめ

転載: juejin.im/post/7105581965503365127