在 Java 上将一种表结构转换为另一种表结构 [已关闭]

问题描述 投票:0回答:1

我有以下案例。

给定表格:

@Getter
@Setter
@AllArgConstructor
class OldRow {

  String type;
  String name;
  int number;
}
List<OldRow> oldTable
类型 姓名 数量
7 亚历克斯 15
8 亚历克斯 17
9 亚历克斯 15
7 约翰 33
8 约翰 44
9 约翰 54

需要使用java 11+将其转换为以下结构

@Getter
@Setter
@AllArgConstructor
class NewRow {

String Name;
  int type7;
  int type8;
  int type9;
}
List<NewRow> newTable
姓名 类型7 类型8 类型9
亚历克斯 15 17 15
约翰 33 44 54

谢谢你

java java-stream mapping
1个回答
1
投票

在向您提供方法之前,我想强调一下我在您的代码中看到的一些外观错误。

  • 你的java变量名称应该以小写字母开头,首字母大写的名称用于类命名

  • 您应该正确缩进代码,以便您(和其他读者)可以更好地看到代码块

我找不到行数更少的优雅解决方案,因此有人可能会在将来发布它,但这对您有用。我先分享代码,然后在下面解释解决方案。

@Getter
@Setter
@AllArgConstructor
class OldRow {

    String type;
    String name;
    int number;
}

@Getter
@Setter
@AllArgConstructor
class NewRow {

    String name;
    int type7;
    int type8;
    int type9;

    public void printPretty() {
        System.out.println(this.name + " " + this.type7 + " " + this.type8 + " " + this.type9);
    }
}


public class MainClass {
    
    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Set<Object> seen = ConcurrentHashMap.newKeySet();
        return t -> seen.add(keyExtractor.apply(t));
    }

    public static void main(String args[]) {
        List<OldRow> oldRows = new ArrayList<>();
        
        oldRows.add(new OldRow("8","Alex",17)); 
        oldRows.add(new OldRow("7","Alex",15)); 
        oldRows.add(new OldRow("9","Alex",15)); 
        oldRows.add(new OldRow("7","John",33)); 
        oldRows.add(new OldRow("8","John",44)); 
        oldRows.add(new OldRow("9","John",54)); 
        
        Map<String,Integer> type7Map = new HashMap<>();
        Map<String,Integer> type8Map = new HashMap<>();
        Map<String,Integer> type9Map = new HashMap<>();
        
        oldRows.forEach(oldRow -> {
            if(oldRow.type.equals("7")) 
                type7Map.put(oldRow.getName(), oldRow.getNumber());
            if(oldRow.type.equals("8")) 
                type8Map.put(oldRow.getName(), oldRow.getNumber());
            if(oldRow.type.equals("9")) 
                type9Map.put(oldRow.getName(), oldRow.getNumber());
        });
        
        List<NewRow> newRows = oldRows.stream()
            .filter(distinctByKey(OldRow::getName))
            .map(oldRow -> new NewRow(
                    oldRow.name,
                    type7Map.get(oldRow.getName()),
                    type8Map.get(oldRow.getName()),
                    type9Map.get(oldRow.getName())
                ))
            .collect(Collectors.toList());
            
        for(NewRow newRow : newRows) {
            newRow.printPretty();
        }

    }
} 

主体的第一部分是创建示例中的

OldRow
实例。然后创建 3 个映射来保留每个名称的 type7type8type9 值。因为你只有这 3 种类型;我们可以使用静态数量的地图。

通过迭代

oldRows
列表来填充这些映射,然后通过流式传输
NewRow
列表并从
maps
查找类型值,将 oldRows 实体填充到新数组中。

最后是打印语句,以便您可以看到

newRows
数组的最后状态是什么。

© www.soinside.com 2019 - 2024. All rights reserved.