2 votes

Flux Java pour agréger une liste de JSON en groupes

J'ai une liste d'objets en Java, comme ceci.

[
  {
    "applicationNumber": "100400",
    "users": "A",
    "category": "student"
  },
  {
    "applicationNumber": "100400",
    "users":"B",
    "category": "student"
  },
  {
    "applicationNumber": "100400",
    "users":"C",
    "category": "neighbour"
  },
  {
    "applicationNumber": "100400",
    "users": "D",
    "category": "neighbour"
  },
  {
    "applicationNumber": "200543",
    "users": "C",
    "category": "student"
  },
  {
    "applicationNumber": "200543",
    "users": "A",
    "category": "student"
  },
  {
    "applicationNumber": "200543",
    "users":"D",
    "category": "friend"
  }
]

Je souhaite regrouper les utilisateurs sous forme de liste (l'ordre n'a pas d'importance) pour chaque catégorie et pour chaque numéro d'application. Vous pouvez vous référer au fichier json ci-dessous pour vous faire une idée.

[
  {
    "applicationNumber": "100400",
    "users": [
      "A",
      "B"
    ],
    "category": "student"
  },
  {
    "applicationNumber": "100400",
    "users": [
      "C",
      "D"
    ],
    "category": "neighbour"
  },
  {
    "applicationNumber": "200543",
    "users": [
      "C",
      "A"
    ],
    "category": "student"
  },
  {
    "applicationNumber": "200543",
    "users": [
      "D"
    ],
    "category": "friend"
  }
]

J'y parviens en utilisant une boucle for, une table de hachage et des conditions if else. Je souhaite utiliser Java 8 stream pour réaliser la même chose. Est-ce que quelqu'un peut m'aider, je suis nouveau en Java.

PS : Merci d'avance

1voto

Je pense que l'utilisation des flux ici est un peu excessive, mais vous pouvez le faire en deux étapes. Tout d'abord, vous devez utiliser Collectors.groupingBy() pour regrouper vos pojos dans une carte de listes. Ensuite, vous devez réduire chaque liste à une seule valeur en utilisant stream().reduce() .

ObjectMapper mapper = new ObjectMapper()
        .enable(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY);
List<Application> applications = Arrays.asList(mapper.readValue(json, Application[].class));
List<Application> groupedApplications = applications.stream()
        .collect(Collectors.groupingBy(ApplicationKey::of, Collectors.toList()))
        .values().stream()
        .map(apps -> apps.stream().reduce(Application::merge))
        .filter(Optional::isPresent)
        .map(Optional::get)
        .collect(Collectors.toList());

Application.java :

public class Application {
    private String applicationNumber;
    private String category;
    private List<String> users = new ArrayList<>();

    public static Application merge(Application first, Application second) {
        assert ApplicationKey.of(first).equals(ApplicationKey.of(second));
        Application merged = new Application(first.applicationNumber, first.category, first.getUsers());
        merged.users.addAll(second.getUsers());
        return merged;
    }
    //constructor, getters, setters
}

ApplicationKey.java

public class ApplicationKey {
    private String applicationNumber;
    private String category;

    public static ApplicationKey of(Application application) {
        return new ApplicationKey(application.getApplicationNumber(), application.getCategory());
    }

    public ApplicationKey(String applicationNumber, String category) {
        this.applicationNumber = applicationNumber;
        this.category = category;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        ApplicationKey that = (ApplicationKey) o;
        return Objects.equals(applicationNumber, that.applicationNumber) &&
                Objects.equals(category, that.category);
    }

    @Override
    public int hashCode() {
        return Objects.hash(applicationNumber, category);
    }

    //getters, setters
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X