はじめに
レスポンスデータって全要素使うわけではなかったり、ネスト構造になってたり、結構見にくいことが多いと思います。
ということで取得したレスポンスを加工(フィルター, マッピング, ソート)して、自分好みのデータクラスを作成してみました。
ゴール
フィルター(抽出):likeCountが5より大きいもの
マッピング(結合):title,body,likeCount,name
ソート(並び替え):likeCountで降順
加工前 | 加工後 |
---|---|
実装
※コード長くなるため、API使わずにレスポンスを模した自作の簡易データを使ってます。
加工前データクラス定義
使用しないゲッター、セッターは省略してます
public class ArticleResponse {
private String title;
private String body;
private String createdAt;
private int likeCount;
private User user;
public ArticleResponse(String title, String body, String createdAt, int likeCount, User user) {
this.title = title;
this.body = body;
this.createdAt = createdAt;
this.likeCount = likeCount;
this.user = user;
}
public String getTitle() {
return title;
}
public String getBody() {
return body;
}
public int getLikeCount() {
return likeCount;
}
public User getUser() {
return user;
}
}
public class User {
private String name;
private int id;
private int followeesCount;
private int followersCount;
public User(String name, int id, int followeesCount, int followersCount) {
this.name = name;
this.id = id;
this.followeesCount = followeesCount;
this.followersCount = followersCount;
}
public String getName() {
return name;
}
}
加工データクラス定義
使用しないゲッター、セッターは省略してます
public class ArticleBusinessModel {
private String title;
private String body;
private int likeCount;
private String name;
public ArticleBusinessModel(String title, String body, int likeCount, String name) {
this.title = title;
this.body = body;
this.likeCount = likeCount;
this.name = name;
}
public int getLikeCount() {
return likeCount;
}
}
データを加工
public class ArticleRepository {
private ArrayList<ArticleResponse> responses = sampleResponseData(); // 加工前のサンプルデータ
public List<ArticleBusinessModel> mapping() {
List<ArticleBusinessModel> processedData = new ArrayList<ArticleBusinessModel>();
for (ArticleResponse article : responses) {
if (article.getLikeCount() > 5) {
processedData.add(new ArticleBusinessModel(
article.getTitle(),
article.getBody(),
article.getLikeCount(),
article.getUser().getName())
);
}
}
// 並び替え
processedData.sort(Comparator.comparing(ArticleBusinessModel::getLikeCount).reversed());
// 中身見るためにJsonに変換
Gson gson = new Gson();
Log.i("元データ:", gson.toJson(responses));
Log.i("加工データ:", gson.toJson(processedData));
return processedData;
}
// サンプルデータ作成
private ArrayList<ArticleResponse> sampleResponseData() {
ArrayList<ArticleResponse> dataList = new ArrayList<>();
User user1 = new User("Ichiro", 1, 70, 50);
User user2 = new User("Jiro", 2, 40, 10);
User user3 = new User("Saburo", 3, 20, 5);
User user4 = new User("Shiro", 4, 10, 5);
dataList.add(new ArticleResponse("Java", "静的型付け言語です", "2021/3/1", 10, user1));
dataList.add(new ArticleResponse("Ruby", "動的型付け言語です", "2021/3/2", 8, user2));
dataList.add(new ArticleResponse("Swift", "静的型付け言語です", "2021/3/2",14, user3));
dataList.add(new ArticleResponse("NoCode", "ノーコードです", "2021/3/3", 3, user4));
return dataList;
}
}
【解説】データをソート
processedData.sort(Comparator.comparing(ArticleBusinessModel::getLikeCount).reversed());
- ポイント
- Comparatable.comparing(クラス名::値) で指定の値で比較することできる
- reversed()で降順
【解説】データをフィルターしてマッピング(普通のfor文の場合)
// memo: ArrayList<ArticleResponse> responses = sampleResponseData();
// // 加工データを格納する入れ物を用意
List<ArticleBusinessModel> processedData = new ArrayList<ArticleBusinessModel>();
for (int i = 0; i < responses.size(); i++ ) {
if (responses.get(i).getLikeCount() > 5) {
processedData.add(new ArticleBusinessModel(
responses.get(i).getTitle(),
responses.get(i).getBody(),
responses.get(i).getLikeCount(),
responses.get(i).getUser().getName())
);
}
}
これでもいいのですが、拡張for文を使うともっとスマートに書けます。
拡張for文について
複数要素をもつ配列やコレクションに対して、要素を1つずつ順番に取り出して処理をしてくれます。
- 拡張for文の書き方
for (型名 変数名 : 配列名) {}
- 拡張for文の使い所
- リスト内のすべての要素に対して1つずつ繰り返し処理をするとき
- リストの何番目が必要という要件がないとき(順番関係なく処理したいとき)
【解説】データをフィルターしてマッピング(拡張for文の場合)
// memo: ArrayList<ArticleResponse> responses = sampleResponseData();
// 加工データを格納する入れ物を用意
List<ArticleBusinessModel> processedData = new ArrayList<ArticleBusinessModel>();
for (ArticleResponse article : responses) {
if (article.getLikeCount() > 5) {
processedData.add(new ArticleBusinessModel(
article.getTitle(),
article.getBody(),
article.getLikeCount(),
article.getUser().getName())
);
}
}
データ加工を実行
本来はViewModelを経由すべきだがコード長くなるので割愛
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ArticleRepository articleRepository = new ArticleRepository();
articleRepository.mapping();
}
}
最後に
次回はStreamを使ってデータ加工する方法を紹介。
レスポンスデータを加工する(Stream)
参考URL
https://qiita.com/takahirocook/items/470b2858de1a4f99b334
https://cartman0.hatenablog.com/entry/2016/02/29/032507
ありがとうございました!