Cómo recoger las propiedades de la lista <> Mapa de propiedad única usando MultiMap?

Hearaman:

Tengo Lista de historias. Usando única property(id)falta que a la palabra clave a cobro revertido y la focalización como lista de valores. ¿Puedo hacer esto con MultiMap? ¿O hay otra biblioteca para este?

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

La salida deseado tiene como esto:

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

Probar mi código de tratado de la siguiente manera:

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 sólo puede almacenar varios valores por clave, pero lo que desea es combinar esos valores múltiples de manera que se obtiene un elemento que tiene el mismo ID y el título, así como una colección de palabras clave y la información de orientación. Por lo tanto, probablemente sería mejor tener ya sea algo así MultiStoryo ya tiene Storycontener esas colecciones.

Me gustaría sugerir el uso de objetos propios en lugar de sólo los mapas, pero con mapas y Java 8 lambdas que podría utilizar compute(), etc para construir mapas que contienen colecciones y combinar mapas que no lo hacen.

Aquí está un ejemplo de cómo se haría con los mapas. Tenga en cuenta que esto es muy mal estilo y un ejemplo usando POJOs adecuados seguirá:

Exención de responsabilidad: ejemplo basado en el código de la OP, no se recomienda (texto leído anteriormente)

//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") );
});

El uso de POJOs

He aquí un ejemplo muy simplificado de cómo se haría con objetos propios de Java (POJO). Tenga en cuenta que los están destinados a parecerse a su código tanto como sea posible y hay un montón de otras cuestiones, pero abordando los que serían demasiado aquí y mejor código diseñado sería mucho más grande y probablemente más difícil de entender - después de todo es sólo la intención se puede mostrar la diferencia.

En primer lugar vamos a definir nuestras clases (para simplificar hice el público campos, usted normalmente no hace eso):

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 ;
  }
}

A continuación, vamos a reiterar el código anterior:

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 );
});

Como se puede ver, no hay moldes necesarios y está claro qué campos están disponibles (aunque no necesariamente llena), que hace que sea más fácil de razonar acerca de los errores de código y al contado (el compilador puede ayudar mucho aquí, que no podía para de el ejemplo que utiliza mapas).

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=224457&siteId=1
Recomendado
Clasificación