JAVA

Java Stream api 를 이용한 파싱

방금시작한사람 2020. 6. 18. 14:41

개인 프로젝트 하던 중, 외부에서 받아온 데이터를 가공해야하는 일이 생겼다.

 

이런식으로 데이터를 받아온다.

{
"operatorpvp_roundlost:3:F:infinite": 18,
"operatorpvp_headshot:3:8:infinite": 21,
"operatorpvp_death:3:A:infinite": 37,
"operatorpvp_death:4:1:infinite": 421,
 .. 

}

 

아래는 모든 입력이다.

더보기

{
"operatorpvp_roundlost:3:F:infinite": 18,
"operatorpvp_headshot:3:8:infinite": 21,
"operatorpvp_death:3:A:infinite": 37,
"operatorpvp_death:4:1:infinite": 421,
"operatorpvp_death:2:13:infinite": 11,
"operatorpvp_meleekills:2:4:infinite": 1,
"operatorpvp_roundlost:4:1:infinite": 326,
"operatorpvp_kills:5:2:infinite": 180,
"operatorpvp_roundlost:2:13:infinite": 8,
"operatorpvp_roundlost:1:1:infinite": 15,
"operatorpvp_totalxp:1:16:infinite": 1650,
"operatorpvp_death:2:D:infinite": 104,
"operatorpvp_totalxp:3:3:infinite": 1003945,
"operatorpvp_timeplayed:3:E:infinite": 27571,
"operatorpvp_headshot:3:6:infinite": 8,
"operatorpvp_totalxp:2:14:infinite": 2600,
"operatorpvp_kills:3:C:infinite": 100,
"operatorpvp_death:2:10:infinite": 92,
"operatorpvp_roundlost:3:E:infinite": 91,
"operatorpvp_roundlost:5:2:infinite": 170,
"operatorpvp_headshot:3:12:infinite": 68,
"operatorpvp_roundlost:6:16:infinite": 1,
"operatorpvp_death:2:B:infinite": 10,
"operatorpvp_roundlost:2:A:infinite": 1,
"operatorpvp_timeplayed:3:B:infinite": 180482,
"operatorpvp_death:3:12:infinite": 126,
"operatorpvp_headshot:2:3:infinite": 50,
"operatorpvp_roundwon:2:D:infinite": 55,
"operatorpvp_roundwon:2:6:infinite": 38,
"operatorpvp_death:3:5:infinite": 69,
"operatorpvp_death:2:16:infinite": 31,
"operatorpvp_headshot:3:C:infinite": 34,
"operatorpvp_death:4:4:infinite": 94,
"operatorpvp_meleekills:3:8:infinite": 4,
"operatorpvp_totalxp:3:D:infinite": 440783,
"operatorpvp_kills:3:2:infinite": 377,
"operatorpvp_kills:2:11:infinite": 100,
"operatorpvp_kills:3:F:infinite": 33,
"operatorpvp_kills:3:8:infinite": 264,
"operatorpvp_roundwon:7:16:infinite": 2,
"operatorpvp_totalxp:4:5:infinite": 850245,
"operatorpvp_totalxp:2:D:infinite": 270105,
"operatorpvp_timeplayed:1:1:infinite": 5991,
"operatorpvp_meleekills:4:3:infinite": 1,
"operatorpvp_death:3:C:infinite": 85,
"operatorpvp_roundwon:3:E:infinite": 53,
"operatorpvp_death:2:6:infinite": 57,
"operatorpvp_meleekills:4:1:infinite": 2,
"operatorpvp_timeplayed:3:1:infinite": 24529,
"operatorpvp_roundlost:4:2:infinite": 7,
"operatorpvp_headshot:1:2:infinite": 5,
"operatorpvp_roundwon:3:A:infinite": 26,
"operatorpvp_roundlost:1:2:infinite": 7,
"operatorpvp_roundlost:2:10:infinite": 64,
"operatorpvp_kills:4:E:infinite": 16,
"operatorpvp_headshot:2:10:infinite": 29,
"operatorpvp_timeplayed:2:D:infinite": 28898,
"operatorpvp_meleekills:3:7:infinite": 8,
"operatorpvp_totalxp:2:13:infinite": 13990,
"operatorpvp_totalxp:2:7:infinite": 166028,
"operatorpvp_roundwon:4:1:infinite": 247,
"operatorpvp_roundwon:5:3:infinite": 8,
"operatorpvp_headshot:3:7:infinite": 205,
"operatorpvp_headshot:3:D:infinite": 53,
"operatorpvp_timeplayed:4:2:infinite": 3460,
"operatorpvp_roundwon:2:7:infinite": 41,
"operatorpvp_totalxp:2:9:infinite": 41583,
"operatorpvp_roundlost:2:1:infinite": 70,
"operatorpvp_death:3:6:infinite": 33,
"operatorpvp_roundwon:4:2:infinite": 10,
"operatorpvp_totalxp:2:4:infinite": 256800,
"operatorpvp_totalxp:5:5:infinite": 168798,
"operatorpvp_roundlost:3:D:infinite": 78,
"operatorpvp_totalxp:3:11:infinite": 58010,
"operatorpvp_headshot:2:2:infinite": 3,
"operatorpvp_timeplayed:5:3:infinite": 3666,
"operatorpvp_timeplayed:4:E:infinite": 4397,
"operatorpvp_roundlost:4:E:infinite": 13,
"operatorpvp_kills:2:5:infinite": 20,
"operatorpvp_headshot:3:B:infinite": 271,
"operatorpvp_totalxp:3:10:infinite": 5000,
"operatorpvp_totalxp:3:C:infinite": 235620,
"operatorpvp_timeplayed:3:5:infinite": 19133,
"operatorpvp_roundwon:3:B:infinite": 520,
"operatorpvp_roundlost:3:A:infinite": 25,
"operatorpvp_timeplayed:2:7:infinite": 17588,
"operatorpvp_kills:2:16:infinite": 24,
"operatorpvp_roundlost:2:11:infinite": 101,
"operatorpvp_headshot:4:3:infinite": 34,
"operatorpvp_headshot:2:8:infinite": 56,
"operatorpvp_headshot:2:C:infinite": 1,
"operatorpvp_totalxp:3:7:infinite": 1480830,
"operatorpvp_timeplayed:2:A:infinite": 386,
"operatorpvp_headshot:5:1:infinite": 78,
"operatorpvp_timeplayed:4:5:infinite": 77302,
"operatorpvp_kills:3:9:infinite": 6,
"operatorpvp_roundwon:3:12:infinite": 88,
"operatorpvp_timeplayed:2:4:infinite": 31167,
"operatorpvp_death:5:1:infinite": 296,
"operatorpvp_roundlost:3:11:infinite": 8,
"operatorpvp_meleekills:3:12:infinite": 1,
"operatorpvp_kills:3:4:infinite": 91,
"operatorpvp_roundwon:3:11:infinite": 16,
"operatorpvp_headshot:4:1:infinite": 143,
"operatorpvp_roundwon:3:7:infinite": 374,
"operatorpvp_timeplayed:4:3:infinite": 30274,
"operatorpvp_headshot:3:9:infinite": 1,
"operatorpvp_timeplayed:5:2:infinite": 57178,
"operatorpvp_kills:4:1:infinite": 369,
"operatorpvp_headshot:3:1:infinite": 31,
"operatorpvp_totalxp:2:1:infinite": 291600,
"operatorpvp_roundwon:2:A:infinite": 1,
"operatorpvp_kills:3:7:infinite": 526,
"operatorpvp_roundwon:4:3:infinite": 68,
"operatorpvp_death:3:3:infinite": 289,
"operatorpvp_timeplayed:3:9:infinite": 3080,
"operatorpvp_headshot:5:3:infinite": 1,
"operatorpvp_death:2:5:infinite": 28,
"operatorpvp_death:3:B:infinite": 591,
"operatorpvp_totalxp:2:8:infinite": 409025,
"operatorpvp_kills:2:9:infinite": 15,
"operatorpvp_headshot:2:9:infinite": 9,
"operatorpvp_kills:2:B:infinite": 12,
"operatorpvp_kills:4:5:infinite": 317,
"operatorpvp_timeplayed:4:4:infinite": 29002,
"operatorpvp_death:3:7:infinite": 397,
"operatorpvp_totalxp:2:10:infinite": 191700,
"operatorpvp_kills:5:3:infinite": 3,
"operatorpvp_timeplayed:3:6:infinite": 12271,
"operatorpvp_meleekills:2:1:infinite": 4,
"operatorpvp_totalxp:3:9:infinite": 29600,
"operatorpvp_kills:3:6:infinite": 35,
"operatorpvp_roundlost:2:2:infinite": 17,
"operatorpvp_totalxp:3:4:infinite": 253075,
"operatorpvp_roundlost:2:8:infinite": 133,
"operatorpvp_headshot:2:1:infinite": 43,
"operatorpvp_roundlost:2:9:infinite": 19,
"operatorpvp_kills:3:11:infinite": 13,
"operatorpvp_meleekills:3:F:infinite": 2,
"operatorpvp_roundwon:2:16:infinite": 15,
"operatorpvp_totalxp:4:4:infinite": 286925,
"operatorpvp_kills:2:A:infinite": 1,
"operatorpvp_roundlost:3:3:infinite": 194,
"operatorpvp_timeplayed:3:4:infinite": 29748,
"operatorpvp_totalxp:3:B:infinite": 2152758,
"operatorpvp_meleekills:5:5:infinite": 2,
"operatorpvp_death:3:4:infinite": 109,
"operatorpvp_roundwon:3:9:infinite": 8,
"operatorpvp_timeplayed:2:5:infinite": 6736,
"operatorpvp_timeplayed:3:A:infinite": 10058,
"operatorpvp_timeplayed:5:4:infinite": 2286,
"operatorpvp_headshot:4:2:infinite": 1,
"operatorpvp_kills:2:8:infinite": 140,
"operatorpvp_timeplayed:2:13:infinite": 2203,
"operatorpvp_death:4:3:infinite": 109,
"operatorpvp_totalxp:4:E:infinite": 47960,
"operatorpvp_death:2:C:infinite": 2,
"operatorpvp_roundlost:4:3:infinite": 80,
"operatorpvp_death:3:11:infinite": 15,
"operatorpvp_totalxp:2:16:infinite": 65045,
"operatorpvp_totalxp:2:6:infinite": 132780,
"operatorpvp_death:4:5:infinite": 247,
"operatorpvp_headshot:5:5:infinite": 18,
"operatorpvp_roundlost:3:10:infinite": 2,
"operatorpvp_roundlost:3:9:infinite": 8,
"operatorpvp_kills:5:5:infinite": 52,
"operatorpvp_meleekills:2:5:infinite": 4,
"operatorpvp_kills:3:A:infinite": 28,
"operatorpvp_totalxp:3:8:infinite": 758825,
"operatorpvp_timeplayed:7:16:infinite": 286,
"operatorpvp_roundwon:3:6:infinite": 39,
"operatorpvp_totalxp:7:16:infinite": 2300,
"operatorpvp_death:2:8:infinite": 176,
"operatorpvp_totalxp:2:A:infinite": 2600,
"operatorpvp_totalxp:2:11:infinite": 277065,
"operatorpvp_meleekills:2:10:infinite": 1,
"operatorpvp_meleekills:3:A:infinite": 1,
"operatorpvp_roundlost:3:7:infinite": 238,
"operatorpvp_timeplayed:2:14:infinite": 134,
"operatorpvp_timeplayed:3:2:infinite": 106954,
"operatorpvp_headshot:1:1:infinite": 1,
"operatorpvp_roundlost:3:12:infinite": 89,
"operatorpvp_totalxp:4:1:infinite": 1048035,
"operatorpvp_roundlost:3:B:infinite": 386,
"operatorpvp_totalxp:2:B:infinite": 28450,
"operatorpvp_roundwon:2:1:infinite": 97,
"operatorpvp_headshot:2:D:infinite": 36,
"operatorpvp_totalxp:6:16:infinite": 100,
"operatorpvp_roundlost:4:5:infinite": 169,
"operatorpvp_roundwon:3:5:infinite": 37,
"operatorpvp_timeplayed:2:8:infinite": 45158,
"operatorpvp_totalxp:3:6:infinite": 107455,
"operatorpvp_roundlost:5:5:infinite": 42,
"operatorpvp_death:2:11:infinite": 126,
"operatorpvp_death:2:7:infinite": 61,
"operatorpvp_totalxp:5:2:infinite": 512270,
"operatorpvp_death:3:8:infinite": 214,
"operatorpvp_death:3:9:infinite": 10,
"operatorpvp_totalxp:4:3:infinite": 298225,
"operatorpvp_kills:1:2:infinite": 9,
"operatorpvp_roundlost:2:7:infinite": 47,
"operatorpvp_headshot:3:F:infinite": 19,
"operatorpvp_roundlost:3:8:infinite": 135,
"operatorpvp_roundlost:2:16:infinite": 24,
"operatorpvp_meleekills:3:4:infinite": 1,
"operatorpvp_timeplayed:2:B:infinite": 2841,
"operatorpvp_timeplayed:3:10:infinite": 380,
"operatorpvp_death:3:2:infinite": 405,
"operatorpvp_headshot:2:16:infinite": 11,
"operatorpvp_headshot:3:E:infinite": 29,
"operatorpvp_kills:1:1:infinite": 12,
"operatorpvp_headshot:4:5:infinite": 92,
"operatorpvp_kills:3:B:infinite": 678,
"operatorpvp_roundlost:2:D:infinite": 84,
"operatorpvp_meleekills:3:C:infinite": 1,
"operatorpvp_death:2:2:infinite": 35,
"operatorpvp_roundwon:5:2:infinite": 105,
"operatorpvp_meleekills:3:D:infinite": 2,
"operatorpvp_kills:5:4:infinite": 5,
"operatorpvp_timeplayed:2:16:infinite": 7763,
"operatorpvp_kills:2:10:infinite": 74,
"operatorpvp_meleekills:3:3:infinite": 1,
"operatorpvp_headshot:3:3:infinite": 127,
"operatorpvp_kills:4:3:infinite": 82,
"operatorpvp_headshot:2:13:infinite": 1,
"operatorpvp_timeplayed:1:16:infinite": 83,
"operatorpvp_death:3:F:infinite": 28,
"operatorpvp_timeplayed:2:C:infinite": 609,
"operatorpvp_headshot:3:4:infinite": 17,
"operatorpvp_totalxp:5:3:infinite": 27425,
"operatorpvp_roundwon:5:1:infinite": 173,
"operatorpvp_totalxp:3:F:infinite": 126185,
"operatorpvp_roundlost:3:6:infinite": 22,
"operatorpvp_roundlost:2:4:infinite": 66,
"operatorpvp_kills:2:13:infinite": 6,
"operatorpvp_death:2:9:infinite": 25,
"operatorpvp_death:7:16:infinite": 2,
"operatorpvp_roundlost:3:C:infinite": 64,
"operatorpvp_timeplayed:2:1:infinite": 33276,
"operatorpvp_kills:3:E:infinite": 80,
"operatorpvp_timeplayed:3:3:infinite": 89272,
"operatorpvp_totalxp:3:E:infinite": 225610,
"operatorpvp_totalxp:4:2:infinite": 32550,
"operatorpvp_roundwon:2:2:infinite": 30,
"operatorpvp_meleekills:2:3:infinite": 2,
"operatorpvp_meleekills:2:13:infinite": 1,
"operatorpvp_kills:2:C:infinite": 2,
"operatorpvp_timeplayed:2:2:infinite": 9874,
"operatorpvp_death:3:D:infinite": 130,
"operatorpvp_timeplayed:2:11:infinite": 34234,
"operatorpvp_roundwon:3:C:infinite": 55,
"operatorpvp_kills:2:D:infinite": 91,
"operatorpvp_timeplayed:2:9:infinite": 6191,
"operatorpvp_headshot:3:2:infinite": 148,
"operatorpvp_headshot:4:4:infinite": 25,
"operatorpvp_timeplayed:2:10:infinite": 23324,
"operatorpvp_roundwon:3:3:infinite": 256,
"operatorpvp_headshot:3:11:infinite": 5,
"operatorpvp_roundwon:2:9:infinite": 10,
"operatorpvp_roundlost:2:C:infinite": 1,
"operatorpvp_meleekills:3:2:infinite": 2,
"operatorpvp_roundwon:5:5:infinite": 39,
"operatorpvp_roundwon:2:5:infinite": 19,
"operatorpvp_totalxp:5:4:infinite": 18250,
"operatorpvp_death:5:5:infinite": 58,
"operatorpvp_roundwon:3:1:infinite": 71,
"operatorpvp_roundwon:2:C:infinite": 2,
"operatorpvp_timeplayed:3:7:infinite": 124368,
"operatorpvp_totalxp:3:12:infinite": 434810,
"operatorpvp_totalxp:3:A:infinite": 107750,
"operatorpvp_headshot:2:5:infinite": 5,
"operatorpvp_roundwon:2:B:infinite": 7,
"operatorpvp_kills:2:4:infinite": 79,
"operatorpvp_kills:4:4:infinite": 87,
"operatorpvp_roundlost:5:4:infinite": 5,
"operatorpvp_headshot:4:E:infinite": 6,
"operatorpvp_kills:2:14:infinite": 1,
"operatorpvp_roundwon:2:10:infinite": 52,
"operatorpvp_kills:2:7:infinite": 76,
"operatorpvp_totalxp:1:1:infinite": 38525,
"operatorpvp_roundwon:4:4:infinite": 78,
"operatorpvp_totalxp:2:2:infinite": 112580,
"operatorpvp_timeplayed:4:1:infinite": 113834,
"operatorpvp_timeplayed:3:D:infinite": 37255,
"operatorpvp_totalxp:3:2:infinite": 998430,
"operatorpvp_kills:3:D:infinite": 168,
"operatorpvp_timeplayed:3:12:infinite": 37295,
"operatorpvp_death:1:1:infinite": 23,
"operatorpvp_death:2:4:infinite": 99,
"operatorpvp_headshot:2:7:infinite": 24,
"operatorpvp_death:3:1:infinite": 77,
"operatorpvp_totalxp:3:1:infinite": 258335,
"operatorpvp_roundwon:2:3:infinite": 71,
"operatorpvp_totalxp:2:5:infinite": 63850,
"operatorpvp_roundwon:3:2:infinite": 229,
"operatorpvp_death:2:A:infinite": 2,
"operatorpvp_headshot:5:4:infinite": 3,
"operatorpvp_death:1:2:infinite": 8,
"operatorpvp_death:4:2:infinite": 11,
"operatorpvp_roundlost:3:5:infinite": 56,
"operatorpvp_kills:5:1:infinite": 228,
"operatorpvp_death:3:E:infinite": 120,
"operatorpvp_timeplayed:2:3:infinite": 25249,
"operatorpvp_kills:2:2:infinite": 30,
"operatorpvp_roundwon:2:8:infinite": 92,
"operatorpvp_kills:3:1:infinite": 76,
"operatorpvp_meleekills:2:B:infinite": 1,
"operatorpvp_kills:3:12:infinite": 148,
"operatorpvp_totalxp:5:1:infinite": 731290,
"operatorpvp_roundwon:2:4:infinite": 84,
"operatorpvp_kills:3:5:infinite": 63,
"operatorpvp_kills:2:6:infinite": 36,
"operatorpvp_kills:4:2:infinite": 9,
"operatorpvp_timeplayed:2:6:infinite": 15514,
"operatorpvp_roundwon:3:8:infinite": 175,
"operatorpvp_roundlost:4:4:infinite": 63,
"operatorpvp_roundwon:2:13:infinite": 4,
"operatorpvp_timeplayed:6:16:infinite": 112,
"operatorpvp_timeplayed:3:11:infinite": 4894,
"operatorpvp_roundlost:3:2:infinite": 298,
"operatorpvp_roundwon:2:11:infinite": 64,
"operatorpvp_death:5:2:infinite": 219,
"operatorpvp_roundwon:5:4:infinite": 6,
"operatorpvp_meleekills:5:2:infinite": 1,
"operatorpvp_death:2:1:infinite": 111,
"operatorpvp_death:6:16:infinite": 1,
"operatorpvp_roundwon:3:4:infinite": 58,
"operatorpvp_totalxp:2:3:infinite": 295125,
"operatorpvp_roundwon:4:5:infinite": 215,
"operatorpvp_headshot:2:4:infinite": 35,
"operatorpvp_headshot:3:5:infinite": 24,
"operatorpvp_timeplayed:1:2:infinite": 2815,
"operatorpvp_roundlost:3:1:infinite": 50,
"operatorpvp_roundwon:3:F:infinite": 33,
"operatorpvp_headshot:5:2:infinite": 71,
"operatorpvp_headshot:2:6:infinite": 13,
"operatorpvp_roundwon:1:2:infinite": 7,
"operatorpvp_death:4:E:infinite": 17,
"operatorpvp_timeplayed:3:8:infinite": 62291,
"operatorpvp_roundlost:2:5:infinite": 18,
"operatorpvp_roundwon:1:1:infinite": 14,
"operatorpvp_kills:2:3:infinite": 108,
"operatorpvp_roundwon:2:14:infinite": 1,
"operatorpvp_death:5:4:infinite": 7,
"operatorpvp_death:2:3:infinite": 93,
"operatorpvp_headshot:2:B:infinite": 1,
"operatorpvp_kills:3:3:infinite": 362,
"operatorpvp_roundwon:3:D:infinite": 110,
"operatorpvp_timeplayed:3:F:infinite": 10194,
"operatorpvp_roundlost:2:6:infinite": 41,
"operatorpvp_meleekills:3:B:infinite": 4,
"operatorpvp_roundwon:1:16:infinite": 1,
"operatorpvp_roundlost:2:B:infinite": 7,
"operatorpvp_totalxp:1:2:infinite": 25050,
"operatorpvp_roundlost:5:3:infinite": 11,
"operatorpvp_timeplayed:5:1:infinite": 81499,
"operatorpvp_roundlost:2:3:infinite": 55,
"operatorpvp_roundlost:5:1:infinite": 227,
"operatorpvp_timeplayed:3:C:infinite": 24052,
"operatorpvp_headshot:3:A:infinite": 14,
"operatorpvp_totalxp:3:5:infinite": 164037,
"operatorpvp_kills:2:1:infinite": 98,
"operatorpvp_roundlost:3:4:infinite": 90,
"operatorpvp_totalxp:2:C:infinite": 5250,
"operatorpvp_roundwon:4:E:infinite": 9,
"operatorpvp_death:5:3:infinite": 14,
"operatorpvp_timeplayed:5:5:infinite": 15925,
"operatorpvp_death:3:10:infinite": 2,
"operatorpvp_headshot:2:11:infinite": 43
}

 

형식은 operatorpvp_(속성):(캐릭터 index):infinite(고정): 값

 

예시는 들면 "operatorpvp_roundlost:3:F:infinite": 20 => 3:F 인덱스를 가진 캐릭터의 패배한 라운드가 20 이라는 뜻

 

하고자하는건 캐릭터 별 속성들을 모아서 아래의 객체 리스트로 만드는 것이다.

public class OperatorDto {    
    String name;
    String operatorIndex;
    String category;
    int kills;
    int death;
    int headShot;
    int meleeKills;
    int totalXp;
    int timePlayed;
    int roundWon;
    int roundLost;
}

 

 

 첫번째로 한것은 같은 인덱스끼리 모으기 위해 grouping by 를 통하여 index가 같은 거 끼리 뭉친다.

String response = getData(~); // 위에 입력된 기다란 데이터
Map<String, Double> operatorMap = new Gson().fromJson(response, Map.class);
Map<String, Map<String, Double>> groupByIndexMap = operatorMap.keySet()
        .stream()
        .collect(Collectors.groupingBy(key -> {
            String[] splitKey = key.split(":");
            String index = splitKey[1] + ":" + splitKey[2];
            return index; // operatorpvp_kills:1:1:infites => 1:1 를 뽑아냄
        }, Collectors.toMap(key -> {
            String prefix = "operatorpvp_";
            String changeKey = key.substring(prefix.length());
            return changeKey.split(":")[0]; // key 부분
        }, key -> operatorMap.get(key)))); // value 부분

그 후 같은 인덱스끼리 모아서 데이터를 맵으로 저장한다.

 

위의 groupByIndexMap 의 타입을 보면 Map<K, List<T>> 타입이 아니라

Map<K, Map<T, D>> 이다.  groupingby 의 결과를 List 뿐만 아니라 Map 이나 Set 으로도 가져올 수 있다!

 

자세한건 https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#groupingBy-java.util.function.Function-java.util.stream.Collector- 아래 docs 에 나와있다..

 

맵으로 만들기 위해 toMap 을 통하여 key, value 를 만드는데 key 가 현재 operatorpvp_속성:인덱스:infinite 로 되어있기 때문에 필요한 부분인 속성만 뽑아내어 키로 만들고 value 는 그대로 가져다 쓰면된다. 

 

그래서 결과를 json 으로 보면

 

{

  "1:A": {

     "kills": 10.0,

     "death": 10.0,

     .. 

  },

  ..

}

 

원하는 대로 인덱스 별로 모아서 정리 끝!

 

남은건 저 Map 을 List<OperatorDto> 로 바꾸면 된다

 

List<OperatorDto> operatorDtoList = new ArrayList<>();

List<OperatorIndex.OperatorInfo> operatorIndexList = OperatorIndex.indexList;
for(OperatorIndex.OperatorInfo operatorIndex : operatorIndexList) {
    String index = operatorIndex.getIndex();
    Map<String, Double> operatorStat = groupByIndexMap.getOrDefault(index, Collections.EMPTY_MAP);

    OperatorDto op = OperatorDto.builder()
        .death(operatorStat.getOrDefault("death", 0.0).intValue())
        .roundLost(operatorStat.getOrDefault("roundlost", 0.0).intValue())
        .roundWon(operatorStat.getOrDefault("roundwon", 0.0).intValue())
        .timePlayed(operatorStat.getOrDefault("timeplayed", 0.0).intValue())
        .totalXp(operatorStat.getOrDefault("totalxp", 0.0).intValue())
        .meleeKills(operatorStat.getOrDefault("meleekills", 0.0).intValue())
        .headShot(operatorStat.getOrDefault("headshot", 0.0).intValue())
        .kills(operatorStat.getOrDefault("kills", 0.0).intValue())
        .operatorIndex(index)
        .category(operatorIndex.getCategory())
        .name(operatorIndex.getName())
        .build();

    operatorDtoList.add(op);
}

 

코드가 조금 무식하긴하다..

 

OperatorIndexList 는 index, name, category 를 가지고 있는 리스트다

{ index : "1:A", name: "ash", category: "atk" } 이런 형식으로 되어있어서 이걸 기준으로 이름과 카테고리를 알 수 있다.

 

파싱한 Map 으로 List 를 만드는 것이 아니라, IndexList 로 List<OperatorDto> 를 만든다.

이유는 신규 오퍼레이터가 나오는 경우, name 과 category를 업데이트 하지 않은 상태에서 index만으로는 무슨 오퍼레이터 인지 구별이 안가기 때문에, 현재 있는 확실히 알고 있는 IndexList로 만든다.

 


 

 

그리고 지금 모든 값이 int 이지만, Map 에서 double 로 받고 다시 int 로 변경하는 이유는

Gson.fromJson 을 할 때, 형변환이 제대로 안된다(..?)

 

다시 알아봐야한다..