[慎用!!!]使用Guava Lists.transform把一种具有泛型bean类型的list转换为另一种bean类型的list

625 阅读1分钟

1.工具类用法

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.util.List;

/**
 * @author linsantiy
 * @date 2021-01-07 18:12
 * @desc 泛型beanList集合的转换
 */
public class ListUtil {

    public static <T, R> List<R> listTransForm(List<T> fromList, Class<R> targetClass) {
        if (CollectionUtils.isEmpty(fromList)) {
            return null;
        }
        return Lists.transform(fromList, new Function<T, R>() {
            @Override
            public R apply(T fromBean) {
                R toBean = null;
                try {
                    toBean = targetClass.newInstance();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                BeanUtils.copyProperties(fromBean, toBean);
                return toBean;
            }
        });
    }
}

注意:

Lists.transform第二个参数,使用的Function为guava类,非jdk1.8的Function

2.Guava Lists.transform坑

请看如下代码

@Test
    public void test24() {
        List<Integer> intList = Lists.newArrayList(100, 200);
        List<Integer> intList1 = Lists.transform(intList, new Function<Integer, Integer>() {
            public Integer apply(Integer input) {
                return input + 100;
            }
        });
        System.out.println(intList1.get(0));
        intList.set(0, 1000);
        System.out.println(intList1.get(0));
    }

未看过Lists.transform源码的同学会认为打印出来的结果是相同的。其实不然,打印结果如下:

200
1100

细看Lists.transform源码,摘要部分代码

  public static <F, T> List<T> transform(
      List<F> fromList, Function<? super F, ? extends T> function) {
    return (fromList instanceof RandomAccess)
        ? new TransformingRandomAccessList<>(fromList, function)
        : new TransformingSequentialList<>(fromList, function);
  }
  
      @Override
    public T get(int index) {
      return function.apply(fromList.get(index));
    }
  
  @Override
    public ListIterator<T> listIterator(final int index) {
      return new TransformedListIterator<F, T>(fromList.listIterator(index)) {
        @Override
        T transform(F from) {
          return function.apply(from);
        }
      };
    }

1.Lists.transform方法返回的并非转换list之后的结果,而是TransformingRandomAccessList对象或者TransformingSequentialList对象

2.每次调用get方法,都会重新调用自定义的function方法,因此,每次调用得到的结果不同

3.listIterator方法同理

因此Guava Lists.transform方法慎用!!!