在 Java 上将一个 table 结构翻译成另一个

Translate one table structure to other on Java

我有以下案例。

给定 table:

@Getter
@Setter
@AllArgConstructor
class OldRow {

  String type;
  String name;
  int number;
}
List<OldRow> oldTable
type Name Number
7 Alex 15
8 Alex 17
9 Alex 15
7 John 33
8 John 44
9 John 54

需要使用 java 11+

将其转换为以下结构
@Getter
@Setter
@AllArgConstructor
class NewRow {

String Name;
  int type7;
  int type8;
  int type9;
}
List<NewRow> newTable
Name type7 type8 type9
Alex 15 17 15
John 33 44 54

谢谢

在给你一个方法之前,我想强调一下我在你的代码中看到的一些装饰性错误。

  • 你的java变量名应该以lower-case字母开头首字母大写的名字是用于 Class 命名.

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

我找不到行数更少的优雅解决方案,因此将来可能有人 post 但这对你有用。先把代码分享出来,下面再说明解决方法

@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 值。因为你只有这三种类型;我们可以使用静态数量的地图。

这些映射通过迭代 oldRows 列表来填充,然后 NewRow 实体通过流式传输 oldRows 列表并从 地图.

最后,打印语句,这样你就可以看到newRows数组的最后状态是什么。