使用java 8 lambda可以减少单行代码吗?

时间:2016-02-03 08:07:48

标签: java lambda

记录从db获取,我可以减少到行以下。

List<Object[]> rows = query.getResultList();
List<Map<Object, Object>> results= new ArrayList<Map<Object, Object>>();

for (Iterator<Object[]> iterator = rows.iterator(); iterator.hasNext()) {
    Object[] objects = (Object[]) iterator.next();
    HashMap d= new HashMap();
    d.put("name", objects[0]);
    d.put("id", objects[1]);
    results.add(d);
}

2 个答案:

答案 0 :(得分:2)

这看起来像是new Java 9 API的完美用例:

List<Map<Object, Object>> results=rows.stream()
    .map(objects -> Map.<Object,Object>of("name", objects[0], "id", objects[1]))
    .collect(Collectors.toList());

或者,如果您不坚持地图键为Object

List<Map<String, Object>> results=rows.stream()
    .map(objects -> Map.of("name", objects[0], "id", objects[1]))
    .collect(Collectors.toList());

如果没有这个,就没有简洁的方法来创建这样的地图(这就是将新方法添加到API中的原因)。直接的方法是使用循环或自己创建地图工厂方法,如fabian’s answer所示。

他的“我写过的最丑陋的单线之一”确实不是很推荐,但是,它可以简化:

List<Map<Object, Object>> results = rows.stream()
    .map(x->Stream.of(0,1).collect(Collectors.toMap(i->i==0?(Object)"name":"id",i->x[i])))
    .collect(Collectors.toList());

这是一个单一的陈述,或具有适当格式的“单行”,但由于你几乎可以把所有东西都放在一行中,所以“单行”这个词无论如何都没什么意义。

尽管是单一陈述,但与直接的for-each循环相比,代码并不少......

答案 1 :(得分:1)

减少到单行?不推荐它。你可以使用辅助方法重写它,你可以使用它来使它成为一个单行:

public static Map<Object, Object> arrayToMap(Object[] objects) {
    HashMap<Object, Object> d = new HashMap<>();
    d.put("name", objects[0]);
    d.put("id", objects[1]);
    return d;
}
    List<Map<Object, Object>> results
            = rows.stream().map(ClassName::arrayToMap).collect(Collectors.toCollection(ArrayList<Map<Object, Object>>::new));

另一种不使用lambdas来简化代码(但绝对不止一行)的方法是使用增强的for循环:

for (Object[] objects : rows) {
    HashMap<Object, Object> d= new HashMap<>();
    d.put("name", objects[0]);
    d.put("id", objects[1]);
    results.add(d);
}
PS:发布这段代码真的伤害了我的感觉,但这是我写过的最丑陋的单行之一(它也有不理想的性能):

List<Map<Object, Object>> results
                = rows.stream().map(x -> Arrays.stream(new Integer[] {0, 1}).collect(Collectors.<Integer, Object, Object>toMap(i -> new String[]{"name", "id"}[i], i -> x[i]))).collect(Collectors.toCollection(ArrayList<Map<Object, Object>>::new));