Java 8流映射字符串到MyObject



我有一个List<String> tennisLines,它包含几行关于网球比赛的信息,每行包含一场网球比赛的信息,比赛名称、地点、回合、获胜者、输家、日期等,以分号分隔。

每个锦标赛都有一个唯一的名称,并包含几场网球比赛。我创建了一个TennisTournament类,其中包括锦标赛的名称、地点和相关的网球比赛List<TennisMatch>等。TennisMatch类包含赢家、输家和回合。

我试图将列表tennisLines转换为List<TennisTournament> tennisTournamentList,因此基本上将每行转换为TennisMatchs实例,并将每组网球比赛添加到网球比赛列表中,以最终创建TennisTournament对象。
我创建了一个流Stream<String> streamLines,我不知道如何将它们映射到一个包含另一个对象的对象。

这是列表的摘录,它最终应该是一个TennisTournament对象,它也包含一个大小为27的列表List<TennisMatch>

location;tournament;match_date;series;court;surface;round;best_of;winner;loser;wrank;lrank;wpts;lpts;w1;l1;w2;l2;w3;l3;w4;l4;w5;l5;tourney_id
Lyon;Lyon Open;2019-05-19;ATP250;Outdoor;Clay;1st Round;3;Millman J.;Andujar P.;55;93;875;608;6;1;6;3;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-19;ATP250;Outdoor;Clay;1st Round;3;Tsonga J.W.;Lajovic D.;85;33;633;1316;7;6;6;4;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-20;ATP250;Outdoor;Clay;1st Round;3;Humbert U.;Norrie C.;61;41;823;1055;6;1;6;3;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-20;ATP250;Outdoor;Clay;1st Round;3;Johnson S.;Harris L.;59;89;850;617;6;2;7;6;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-20;ATP250;Outdoor;Clay;1st Round;3;Herbert P.H.;Chardy J.;42;40;1053;1065;6;2;7;5;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-20;ATP250;Outdoor;Clay;1st Round;3;Lamasine T.;Sinner J.;270;229;153;215;6;0;7;6;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-20;ATP250;Outdoor;Clay;1st Round;3;Diez S.;Tomic B.;262;82;165;665;6;4;4;1;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-20;ATP250;Outdoor;Clay;1st Round;3;Fritz T.;Vesely J.;46;105;1010;543;7;5;7;6;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-20;ATP250;Outdoor;Clay;1st Round;3;Gasquet R.;Janvier M.;39;199;1105;263;6;7;6;2;7;6;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-21;ATP250;Outdoor;Clay;1st Round;3;Moutet C.;Opelka R.;117;58;495;853;6;3;2;6;7;6;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-21;ATP250;Outdoor;Clay;1st Round;3;Cuevas P.;Hurkacz H.;50;43;963;1040;6;4;6;4;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-21;ATP250;Outdoor;Clay;1st Round;3;Paire B.;Mcdonald M.;51;65;938;796;3;6;7;6;6;1;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-21;ATP250;Outdoor;Clay;2nd Round;3;Johnson S.;Herbert P.H.;59;42;850;1053;7;6;5;7;6;1;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-21;ATP250;Outdoor;Clay;2nd Round;3;Auger-Aliassime F.;Millman J.;28;55;1344;875;7;6;7;5;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-22;ATP250;Outdoor;Clay;2nd Round;3;Paire B.;Cuevas P.;51;50;938;963;6;4;6;3;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-22;ATP250;Outdoor;Clay;2nd Round;3;Shapovalov D.;Humbert U.;23;61;1425;823;2;6;7;6;6;2;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-22;ATP250;Outdoor;Clay;2nd Round;3;Fritz T.;Gasquet R.;46;39;1010;1105;0;0;0;0;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-22;ATP250;Outdoor;Clay;2nd Round;3;Bautista Agut R.;Moutet C.;21;117;1690;495;4;6;6;4;6;3;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-22;ATP250;Outdoor;Clay;2nd Round;3;Tsonga J.W.;Diez S.;85;262;633;165;3;6;7;6;6;3;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-22;ATP250;Outdoor;Clay;2nd Round;3;Basilashvili N.;Lamasine T.;18;270;1925;153;7;5;7;5;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-23;ATP250;Outdoor;Clay;Quarterfinals;3;Fritz T.;Bautista Agut R.;46;21;1010;1690;6;7;6;3;6;4;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-23;ATP250;Outdoor;Clay;Quarterfinals;3;Paire B.;Shapovalov D.;51;23;938;1425;6;3;4;6;7;6;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-23;ATP250;Outdoor;Clay;Quarterfinals;3;Basilashvili N.;Tsonga J.W.;18;85;1925;633;6;4;6;4;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-23;ATP250;Outdoor;Clay;Quarterfinals;3;Auger-Aliassime F.;Johnson S.;28;59;1344;850;6;4;2;6;6;4;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-24;ATP250;Outdoor;Clay;Semifinals;3;Paire B.;Fritz T.;51;46;938;1010;6;4;6;2;0;0;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-24;ATP250;Outdoor;Clay;Semifinals;3;Auger-Aliassime F.;Basilashvili N.;28;18;1344;1925;2;6;7;6;6;4;0;0;0;0;2019-031
Lyon;Lyon Open;2019-05-25;ATP250;Outdoor;Clay;The Final;3;Paire B.;Auger-Aliassime F.;51;28;938;1344;6;4;6;3;0;0;0;0;0;0;2019-031

这是tennistourtournament类

public class TennisTournament {
private String location; 
private String name;
private String type;   
private boolean outside = true;
private String surface;       
private LocalDate lastMatchDate;      
private List<TennisMatch> matches = new ArrayList<>();
// constructors, getters, setters, etc.

我已经成功地制作了一个TennisTournament列表,但没有使用流在它们内部匹配:

tennisLines.stream()
.skip(1)
.map(l -> { return l.split(SEPARATOR); }) 
.forEach(c -> {
if (c[ROUND_INDEX].equals(THE_FINAL)){
TennisTournament tournament = 
new TennisTournament(c[LOCATION_INDEX], 
c[TOURNAMENT_INDEX], c[SERIES_INDEX],   
c[COURT_INDEX].equals(OUTDOOR), 
c[SURFACE_INDEX],   
LocalDate.parse(c[MATCH_DATE_INDEX]));
}
tennisTournamentList.add(tournament)
});

假设数组包含所有行,这应该可以工作。您可能需要根据实际应用程序调整一些内容。

经过一番考虑,我修改为使用循环而不是流,因为这是两个独立的数据结构需要被创建。它们可以同时在一个循环中创建。我相信它比我原来的答案更有效率,当然也更紧凑。

引用特定数组元素的索引常量。它们还有助于编写文档。

static int WINNER = 8;
static int LOCATION = 0;
static int TOURNAMENT = 1;
static int DATE = 2;
static int COURT = 4;
static int SURFACE = 5;
static int LOSER = 9;
static int ROUND = 6;
  • 分配一个映射来存储TennisMatch实例。关键是比赛的胜利者
  • 分配一个列表来保存锦标赛获胜者的数据。
Map<String, List<TennisMatch>> matches = new HashMap<>();
List<TennisTournament> tournamentWinners = new ArrayList<>();
  • 遍历行,跳过第一个(列头)
  • 拆分;分隔符
  • 上的行
  • 通过键入最后一轮为获胜者创建TennisTournament实例
  • 为所有条目创建获胜者(键)到获胜匹配列表(值)的映射。
    • 这使用computeIfAbsent方法创建并返回一个列表,如果一个列表不存在。
    • 否则,将使用现有列表填充获胜的匹配项。
for (int i = 1; i < lines.length; i++) {
String[] arr = lines[i].split(";");
if (arr[ROUND].equals("The Final")) {
tournamentWinners.add(new TennisTournament(arr[LOCATION],
arr[TOURNAMENT], arr[COURT], arr[SURFACE],
arr[WINNER], arr[DATE]));
}

matches.computeIfAbsent(arr[WINNER],
v -> new ArrayList<>())
.add(new TennisMatch(arr[WINNER], arr[LOSER],
arr[ROUND]));
}   

现在,为获胜的个人添加比赛是一件简单的事情通过简单地从tennistourtournament实例中获取锦标赛冠军来显示锦标赛并使用它作为匹配映射的键。

for (TennisTournament tourney : tournamentWinners) {
tourney.setMatches(matches.get(tourney.getWinner()));
}

显示结果(在本例中只有一个)

tournamentWinners.forEach(tourney -> {
System.out.println(tourney);
for (TennisMatch m : tourney.getMatches()) {
System.out.println("          " + m);
}
});

打印

[Lyon, Lyon Open, Outdoor, Clay, 2019-05-25]
[Paire B., Mcdonald M., 1st Round]
[Paire B., Cuevas P., 2nd Round]
[Paire B., Shapovalov D., Quarterfinals]
[Paire B., Fritz T., Semifinals]
[Paire B., Auger-Aliassime F., The Final]

这里是类。为了保留"clutter",只有必要的getter和setter如下所示:

class TennisMatch {
String winner;
String loser;
String round;

public TennisMatch(String winner, String loser, String round) {
this.winner = winner;
this.loser = loser;
this.round = round;
}

@Override
public String toString() {
return String.format("[%s, %s, %s]", winner, loser, round);
}
}
class TennisTournament {
String location;
String series;
String court;
String surface;
LocalDate date;
String winner;
List<TennisMatch> matches;

public TennisTournament(String location, String series,
String court, String surface, String winner,
String stringDate) {
this.location = location;
this.series = series;
this.court = court;
this.surface = surface;
this.winner = winner;
this.date = LocalDate.parse(stringDate);
}

public List<TennisMatch> getMatches() {
return matches;
}

public String getWinner() {
return winner;
}

public void setMatches(List<TennisMatch> matches) {
// defensive copy
this.matches = new ArrayList<>(matches);
}

@Override
public String toString() {
return String.format("[%s, %s, %s, %s, %s]", location, series,
court, surface, date);
}
}

最新更新