在 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 个映射以保留每个名称的 type7、type8 和 type9 值。因为你只有这三种类型;我们可以使用静态数量的地图。
这些映射通过迭代 oldRows
列表来填充,然后 NewRow
实体通过流式传输 oldRows
列表并从 地图.
最后,打印语句,这样你就可以看到newRows
数组的最后状态是什么。
我有以下案例。
给定 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 个映射以保留每个名称的 type7、type8 和 type9 值。因为你只有这三种类型;我们可以使用静态数量的地图。
这些映射通过迭代 oldRows
列表来填充,然后 NewRow
实体通过流式传输 oldRows
列表并从 地图.
最后,打印语句,这样你就可以看到newRows
数组的最后状态是什么。