1
0

More than 3 years have passed since last update.

レスポンスデータを加工する(拡張for文)

Last updated at Posted at 2021-03-16

はじめに

レスポンスデータって全要素使うわけではなかったり、ネスト構造になってたり、結構見にくいことが多いと思います。
ということで取得したレスポンスを加工(フィルター, マッピング, ソート)して、自分好みのデータクラスを作成してみました。

ゴール

フィルター(抽出):likeCountが5より大きいもの
マッピング(結合):title,body,likeCount,name
ソート(並び替え):likeCountで降順

加工前 加工後
スクリーンショット 2021-03-16 22.02.13.png

実装

※コード長くなるため、API使わずにレスポンスを模した自作の簡易データを使ってます。

加工前データクラス定義

使用しないゲッター、セッターは省略してます

ArticleResponse.java
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;
    }
}
User.java
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;
    }
}

加工データクラス定義

使用しないゲッター、セッターは省略してます

ArticleBusinessModel.java
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;
    }
}

データを加工

ArticleRepository.java
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を経由すべきだがコード長くなるので割愛

MainActivity.java
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
ありがとうございました!

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0