Comment collecter les propriétés de liste <> Carte de propriété unique en utilisant MultiMap?

Hearaman:

Je Liste des histoires. L' utilisation unique de property(id)défaut I à mot - clé et le ciblage Collect liste des valeurs. Puis - je faire avec MultiMap? Ou est - il d' autres bibliothèques pour cela?

[{
    id = 1,
    title = Onboarding,
    keyword = new joinee,
    targeting = finance
}, {
    id = 1,
    title = Onboarding,
    keyword = training,
    targeting = HR
}]

La sortie souhaitée doit comme ceci:

{
    id = 1,
    title = Onboarding,
    keyword = [new joinee,training], //may be keywords - plural
    targeting = [HR,finance]
} 

Exemple mon code essayé comme suit:

package prac;
import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.Multimap;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JavaPrac {
    public static void main(String[] args) {
        Multimap<Integer, Map> multiMap = ArrayListMultimap.create();

        List<Map> stories=new ArrayList();

        Map story1=new HashMap();
        story1.put("id", 1);
        story1.put("title", "Onboarding");
        story1.put("keyword","new joinee");
        story1.put("targeting","finance");

        Map story2=new HashMap();
        story2.put("id", 1);
        story2.put("title", "Onboarding");
        story2.put("keyword","training");
        story2.put("targeting","HR");

        stories.add(story1);
        stories.add(story2);

        System.out.println(stories);

        stories.forEach((story) -> {
            multiMap.put((Integer) story.get("id"), story);
        });
    }
}
Thomas:

Un multimap ne peut stocker plusieurs valeurs par clé , mais ce que vous voulez est de combiner ces multiples valeurs afin que vous obtenez un élément qui a le même identifiant et le titre ainsi qu'une collection de mots - clés et des informations de ciblage. Ainsi , il serait probablement préférable d'avoir soit quelque chose comme MultiStoryou déjà Storycontenir ces collections.

Je suggère d' utiliser des objets appropriés au lieu de simples cartes , mais avec des cartes et Java 8 lambdas vous pouvez utiliser compute()etc pour construire des cartes qui contiennent des collections et de combiner des cartes qui ne sont pas.

Voici un exemple de la façon dont vous le feriez avec des cartes. Notez que cela est très mauvais style et un exemple en utilisant des POJO appropriés qui va suivre:

Avertissement: exemple basé sur le code de l'OP, non recommandée (texte lu ci-dessus)

//Problem 1: we don't know the type of the values, i.e. we could put anything for "id" etc.
Map<String, Object> story1=new HashMap<>();
story1.put("id", 1);
story1.put("title", "Onboarding");
story1.put("keyword","new joinee");
story1.put("targeting","finance");

Map<String, Object> story2=new HashMap<>();
story2.put("id", 1);
story2.put("title", "Onboarding");
story2.put("keyword","training");
story2.put("targeting","HR");

List<Map<String, Object>> stories=new ArrayList<>();

stories.add(story1);
stories.add(story2);

Map<Integer, Map<String, Object>> combined = new HashMap<>();

stories.forEach((story) -> {
  //Problem 2: because we don't know the type of the values we need a lot of nasty casts
  Map<String, Object> combinedStory = combined.computeIfAbsent( (Integer)story.get( "id" ), k -> new HashMap<String, Object>() );
  combinedStory.put("id", story.get( "id" ) );
  combinedStory.put("title", story.get( "title" ) );

  //Problem 3: the combined map would look a lot like your "story" maps but would contain different types
  ((List<String>)combinedStory.computeIfAbsent( "keyword", v -> new List<String>() )).add( (String)story.get("keyword") );
  ((List<String>)combinedStory.computeIfAbsent( "targeting", v -> new List<String>() )).add( (String)story.get("targeting") );
});

L'utilisation POJO

Voici un exemple très simplifié de la façon dont vous le feriez avec des objets appropriés Java (POJO). Notez que ceux-ci sont censées ressembler à votre code, autant que possible et il y a beaucoup d'autres questions, mais faire face à ces serait beaucoup trop ici et un meilleur code conçu serait beaucoup plus grand et probablement plus difficile à comprendre - après tout cela voulait juste dire vous montrer une différence.

Tout d'abord nous allons définir nos classes (pour simplifier, je fait les champs publics, que vous auriez normalement pas ça):

class Story {
  public final int id;
  public String title;
  public String keyword;
  public String targeting;

  public Story(int storyId) {
    id = storyId ;
  }
}

class MultiStory {
  public final int id;
  public String title;
  public Set<String> keywords = new HashSet<>();
  public Set<String> targetingInfo = new HashSet<>();

  public MultiStory( int storyId ) {
    id = storyId ;
  }
}

Ensuite, nous allons réitèrent le code ci-dessus:

Story story1=new Story( 1 );
story1.title = "Onboarding";
story1.keyword = "new joinee";
story1.targeting = "finance";

Story story2=new Story( 1 );
story2.title = "Onboarding";
story2.keyword = "training";
story2.targeting = "HR";

List<Story> stories=new ArrayList<>();

stories.add(story1);
stories.add(story2);

Map<Integer, MultiStory> combined = new HashMap<>();

stories.forEach((story) -> {
  MultiStory multiStory = combined.computeIfAbsent( story.id, v -> new MultiStory( story.id ) );
  multiStory.title = story.title;
  multiStory.keywords.add( story.keyword );
  multiStory.targetingInfo.add( story.targeting );
});

Comme vous pouvez le voir, il n'y a pas de moulages nécessaires et il est clair que les champs sont disponibles (mais pas nécessairement rempli) ce qui le rend plus facile à raisonner sur les erreurs de code et spot (le compilateur peut aider beaucoup ici qui ne pouvait pas dans l'exemple qui utilise des cartes).

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=224455&siteId=1
conseillé
Classement