Doubt with hashmap [closed]

3

I have the following list:

List<DatosAutores> datosAutor= new ArrayList<DatosAutores>();

    datosAutor.add(new DatosAutores("157","Joaquín  Ordóñez Sedeño","[email protected]","Anuario Mexicano de Derecho Internacional","4027","Derecho","6"));
    datosAutor.add(new DatosAutores("157","Joaquín  Ordóñez Sedeño","[email protected]","Revista Latinoamericana de Derecho Social","4296","Derecho","6"));
    datosAutor.add(new DatosAutores("193","Carlos Arturo  Castro Castro","[email protected]","Palabra Clave (La Plata)","3505","Ciencias de la Información","23"));
    datosAutor.add(new DatosAutores("198","Romeo  Rojas","[email protected]","Colombia Forestal","4239","Agrociencias","28"));
    datosAutor.add(new DatosAutores("198","Romeo  Rojas","[email protected]","Facultad de Ingeniería","4139","Ingeniería","38"));
    datosAutor.add(new DatosAutores("198","Romeo  Rojas","[email protected]","Sociedad y mundo","1211","Sociologia","10"));

How can I get something like the following code?

     /*  157  
     * Joaquín  Ordóñez Sedeño
     * [email protected]
     * Derecho (area:6)
     *   Anuario Mexicano de Derecho Internacional (clave:4027)
     *   Revista Latinoamericana de Derecho Social (clave:4296)
     * 
     * 
     * 198
     * Romeo  Rojas
     * [email protected]
     * Agrociencias (area:28)
     *    Colombia Forestal (clave:4239)
     * Ingeniería  (area:38)
     *    Facultad de Ingeniería (clave:4139)
     * Sociologia (area:10)
     *     Sociedad y mundo (clave:1211)
     * 
     * 193
     * Carlos Arturo  Castro Castro
     * [email protected]
     * Ciencias de la Información (area:23)
     *    Palabra Clave (La Plata)(clave:3505)
     */

I used hashmap to sort the output:

Set<String> duplicado = new HashSet<String>();
    Set<String> set = new HashSet<String>();

    HashMap<DatosAutores,String> uno= new HashMap<DatosAutores,String>();
    HashMap<DatosAutores,String> dos= new HashMap<DatosAutores,String>();




    for(DatosAutores aut: datosAutor){
        if (!set.add(aut.getIdAutor())) {
            duplicado.add(aut.getIdAutor());
            out.println("##"+aut.getIdAutor());
            out.println(aut.getNomAutor());
            out.println(aut.getCorreo());
            out.println(aut.getNombreArea()+" - "+ aut.getClaveArea());
            out.println(".."+aut.getTituloRevista()+" - " +aut.getClaveRevista()+"");
            uno.put(aut,aut.getIdAutor());
        }
        else{
        out.println("**"+aut.getIdAutor()+ " no duplicado");
        out.println(aut.getNomAutor());
        out.println(aut.getCorreo());
        out.println(aut.getNombreArea()+" - "+ aut.getClaveArea());
        out.println(".."+aut.getTituloRevista()+" - "+aut.getClaveRevista()+"");
        dos.put(aut,aut.getIdAutor());
        }
    }
    out.println("duplicado:"+duplicado);
    out.println("set:"+set);


    for (Entry<DatosAutores,String> entry : uno.entrySet()) {
        DatosAutores key = entry.getKey();
        String value = (String) entry.getValue();
        for (Entry<DatosAutores,String> entry2 : dos.entrySet()) {
            DatosAutores key2 = entry2.getKey();
            String value2 = (String) entry2.getValue();

            if(key.getIdAutor().equals(key2.getIdAutor())){
                out.println(key2.getIdAutor()+","+key2.getNomAutor());
                out.println(key2.getCorreo());
                out.println(key.getNombreArea() +" -- "+key2.getNombreArea());
                out.println(key.getTituloRevista()+" -- "+key.getClaveRevista()+", "   +key2.getTituloRevista()+" --- "+key2.getClaveRevista());

            }


        }//fin for 2

    }//fin for 1
    
asked by Fernando Carraro 09.01.2016 в 00:43
source

2 answers

2

A correct choice of data structure will greatly facilitate your work.

Now you have a class DatosAutores that contains an author, an area and a magazine. And a list in which those authors are stored such that:

Lista
|-DatosAutores
|    |- "157"
|    |- "Joaquín  Ordóñez Sedeño"
|    |- "[email protected]"
|    |- "Anuario Mexicano de Derecho Internacional"
|    |- "4027"
|    |-"Derecho"
|    \- "6"
|-DatosAutores
|    |- "157"
|    |- "Joaquín  Ordóñez Sedeño"
|    |- "[email protected]"
|    |- "Revista Latinoamericana de Derecho Social"
|    |- "4296"
|    |- "Derecho"
|    \- "6"
. 
.

With this structure you can only store one area and one journal in each DataAuthors, which means that the author and the areas have to be repeated multiple times.

A more appropriate structure would be the following.

Datos :
|- autores : Map<String, DatosAutores>
  |- "157", DatosAutores
  |         |- "Joaquín  Ordóñez Sedeño"
  |         |- "[email protected]"
  |         \- areas - Map<String, DatosAreas> 
  |             \- "6", DatosAreas
  |                       |-"Derecho"
  |                       \- revistas - Map<String, String>
  |                          |- "4027", "Anuario Mexicano de Derecho Internacional"
  |                          \- "4296", "Revista Latinoamericana de Derecho Social"
  |
  |- "198", DatosAutores
  |         |- "Romeo  Rojas"
  .         .
  .         .

With this structure you only have to store each author once.
And for each author you only have to store each one of the areas where you have magazines only once.

Data contains a Map using the keyword Key String as key (key); and as value (value) a class object DataAuthors.
DataAuthors contains the name and email; and a Map using as key (key) the key of the areas and as value (value) an object of class DatosAreas.
And Data Areas contains the name of the area; and a Map using as key (key) the key of the magazine and as value (value) the name of the magazine.

The code for DatosAreas would be:

import java.util.HashMap;
import java.util.Map;
public class DatosAreas {
    private final String nombre;
    private final Map<String,String> revistas;

    public DatosAreas( String nombre)
    {
        if ( nombre==null )
            throw new IllegalArgumentException( "nombre debe ser no null");
        this.nombre = nombre;
        revistas = new HashMap<>();
    }

    public void añadeRevista( String nombre, String clave )
    {
        if ( nombre==null || clave==null )
            throw new IllegalArgumentException( "nombre y clave deben ser no null");
        revistas.put( clave, nombre);
    }

    public String toString( String clave )
    {
        StringBuilder res = new StringBuilder();
        res.append( "  ").append(nombre).append(" (area:").append(clave)
           .append(")").append(System.lineSeparator());
        for ( Map.Entry<String,String> r : revistas.entrySet() )
        {
            res.append("    ").append(r.getValue()).append(" (clave:")
               .append(r.getKey()).append(")").append(System.lineSeparator());
        }
        return res.toString();
    }
}

The constructor simply assigns the name of the areas, creates an empty HashMap and checks that the name is not null.
añadeRevista checks that the journal name and password are not null. And then call put of HashMap to add the magazine. Hashmap.put deals with the case that we add the same magazine key twice . The second time will be treated as an update, the magazine will not be repeated but the title will be changed to that of the second call.
And toString(String clave) returns a String with the data of the area and the magazines that are in it.

The code of DataAuthors would be:

import java.util.HashMap;
import java.util.Map;
public class DatosAutores {

    private final String nombre;
    private final String email;
    private final Map<String, DatosAreas> areas;

    public DatosAutores( String nombre, String email )
    {
        if ( nombre==null || email==null )
            throw new IllegalArgumentException( "Nombre y email han de ser no null");
        this.nombre = nombre;
        this.email = email;
        areas = new HashMap<>();
    }

    public void añadeRevista( String nombreArea, String claveArea,
            String nombreRevista, String claveRevista )
    {
        DatosAreas area;
        area = areas.get(claveArea);
        if ( area==null )
        {
            area = new DatosAreas(nombreArea);
            areas.put(claveArea, area);
        }
        area.añadeRevista(nombreRevista, claveRevista);
    }

    public String toString( String clave )
    {
        StringBuilder res = new StringBuilder();
        res.append(clave).append(System.lineSeparator());
        res.append(nombre).append(System.lineSeparator());
        res.append(email).append(System.lineSeparator());
        for ( Map.Entry<String,DatosAreas> a : areas.entrySet() )
        {
            res.append( a.getValue().toString( a.getKey() ));
        }
        res.append(System.lineSeparator());
        return res.toString();
    }
}

The constructor assigns name and email checking that they are not null; and create a new HashMap.
añadeRevista checks if that area already exists in the Map of areas of the author. If you do not create a new area. And add to that area (the new one or the one that already existed) the magazine. toString(String clave) generates a String with the data of the author and the data of each areas; which you get by calling toString of each area, which we have already defined before.

Finally the class Data:

import java.util.Map;
import java.util.HashMap;
public class Datos {
    private final Map<String, DatosAutores> autores;
    public Datos()
    {
        autores = new HashMap<>();
    }

    void add( String claveAutor, String nombreAutor, String email,
            String nombreRevista, String claveRevista, 
            String nombreArea, String claveArea)
    {
        DatosAutores dato = autores.get( claveAutor );
        if ( dato==null )
        {
            dato = new DatosAutores(nombreAutor, email);
            autores.put(claveAutor, dato);
        }
        dato.añadeRevista(nombreArea, claveArea, nombreRevista, claveRevista);
    }

    @Override
    public String toString()
    {
        StringBuilder res = new StringBuilder();
        for ( Map.Entry<String,DatosAutores> autor : autores.entrySet() )
        {
            res.append( autor.getValue().toString( autor.getKey() ));
        }
        return res.toString();
    }
}

The constructor simply creates a new HashMap.
add checks if you already have that author, if you do not create it and add it; and then add the magazine to the author.
toString calls the toString method of all the authors and collects the result to have a chain with all the authors, their areas and journals.

With this data structure, adding and printing organized journals is reduced to:

Datos datosAutor = new Datos();
datosAutor.add( "157", "Joaquín  Ordóñez Sedeño", "[email protected]", "Anuario Mexicano de Derecho Internacional", "4027", "Derecho", "6");
datosAutor.add( "157", "Joaquín  Ordóñez Sedeño", "[email protected]", "Revista Latinoamericana de Derecho Social", "4296", "Derecho", "6");
datosAutor.add( "193", "Carlos Arturo  Castro Castro", "[email protected]", "Palabra Clave (La Plata)", "3505", "Ciencias de la Información", "23");
datosAutor.add( "198", "Romeo  Rojas", "[email protected]", "Colombia Forestal", "4239", "Agrociencias", "28");
datosAutor.add( "198", "Romeo  Rojas", "[email protected]", "Facultad de Ingeniería", "4139", "Ingeniería", "38");
datosAutor.add( "198", "Romeo  Rojas", "[email protected]", "Sociedad y mundo", "1211", "Sociologia", "10");
System.out.println( datosAutor );

Obtaining as a result:

198
Romeo  Rojas
[email protected]
  Ingeniería (area:38)
    Facultad de Ingeniería (clave:4139)
  Agrociencias (area:28)
    Colombia Forestal (clave:4239)
  Sociologia (area:10)
    Sociedad y mundo (clave:1211)

157
Joaquín  Ordóñez Sedeño
[email protected]
  Derecho (area:6)
    Revista Latinoamericana de Derecho Social (clave:4296)
    Anuario Mexicano de Derecho Internacional (clave:4027)

193
Carlos Arturo  Castro Castro
[email protected]
  Ciencias de la Información (area:23)
    Palabra Clave (La Plata) (clave:3505)

The data structure itself already organizes everything. There is no need for a loop code checking whether or not there are repetitions and looking for scattered data.
Having a good data organization makes printing simple.

    
answered by 09.01.2016 в 10:36
2

The following code generates an output similar to the one you require:

  • Code:

    // Cargar datos
    Set<String> autorSet = new LinkedHashSet<>();
    Map<String, Set<String>> areaMap = new LinkedHashMap<>();
    Map<String, Set<String>> revistaMap = new LinkedHashMap<>();
    for (DatosAutores aut : datosAutor) {
        String idAutor = aut.getIdAutor();
        autorSet.add(idAutor);
        if (!areaMap.containsKey(idAutor)) {
            areaMap.put(idAutor, new LinkedHashSet<String>());
        }
        String claveArea = aut.getClaveArea();
        areaMap.get(idAutor).add(claveArea);
        if (!revistaMap.containsKey(claveArea)) {
            revistaMap.put(claveArea, new LinkedHashSet<String>());
        }
        String claveRevista = aut.getClaveRevista();
        revistaMap.get(claveArea).add(claveRevista);
    }
    
    // Imprimir datos
    for(String idAutor : autorSet) {
        DatosAutores aut = null;
        for(DatosAutores temp : datosAutor) {
            if (idAutor.equals(temp.getIdAutor())) {
                aut = temp;
                break;
            }
        }
        if (aut != null) {
            System.out.println(idAutor);
            System.out.println(aut.getNomAutor());
            System.out.println(aut.getCorreo());
        }
        for(String claveArea : areaMap.get(idAutor)) {
            for(DatosAutores temp : datosAutor) {
                if (idAutor.equals(temp.getIdAutor()) && claveArea.equals(temp.getClaveArea())) {
                    System.out.printf("%s (area:%s)%n", temp.getNombreArea(), claveArea);
                }
    
            }
            for(String claveRevista : revistaMap.get(claveArea)) {
                for(DatosAutores temp : datosAutor) {
                    if (claveRevista.equals(temp.getClaveRevista())) {
                        System.out.printf("  %s (clave:%s)%n", temp.getTituloRevista(), claveRevista);
                        }
                    }
                }
            }
            System.out.println();
        }
    }
    
  • Exit:

    157
    Joaquín  Ordóñez Sedeño
    [email protected]
    Derecho (area:6)
    Derecho (area:6)
      Anuario Mexicano de Derecho Internacional (clave:4027)
      Revista Latinoamericana de Derecho Social (clave:4296)
    
    193
    Carlos Arturo  Castro Castro
    [email protected]
    Ciencias de la Información (area:23)
      Palabra Clave (La Plata) (clave:3505)
    
    198
    Romeo  Rojas
    [email protected]
    Agrociencias (area:28)
      Colombia Forestal (clave:4239)
    Ingeniería (area:38)
      Facultad de Ingeniería (clave:4139)
    Sociologia (area:10)
      Sociedad y mundo (clave:1211)
    
answered by 09.01.2016 в 07:59