0

I'm making a test for a little more complex task in where I might have repeated elements that I want to avoid using a HashSet.


I wrote the following code which uses getAllEmpresas(), Empresa or Organization is a more complex structure that a DAOJson is retrieveng, but I'm only interested in the names of those organizations...

   public class TestListaDeNombresDeEmpresas {

    RepositorioDeEmpresas repo ;
    HashSet<String> nombresDeEmpresas ;
    List<Empresa> empresas ; 

    public TestListaDeNombresDeEmpresas () throws IOException
    {
        DAOJsonEmpresa dao = new DAOJsonEmpresa() ;
        repo = RepositorioDeEmpresas.getInstance(dao) ;
        empresas = repo.getAllEmpresas() ;
        nombresDeEmpresas = new HashSet<String>();
        fillHashSet();

    }

    public static void main (String [] args) throws IOException
    {
        TestListaDeNombresDeEmpresas test = new TestListaDeNombresDeEmpresas() ;
        System.out.println("Imprimiendo lista de empresas");
        test.imprimirListEmpresas();
        test.fillHashSet();
        System.out.println();
        test.hashSetContainsFirstElement();
        System.out.println("imprimiendo hash...");
        test.imprimirHashNombresEmpresas();
    }

    public void fillHashSet() {

        List<String> nombresDeEmpresasAux = empresas.stream()
                                .map(e -> e.getName()).collect(Collectors.toList()) ;

        nombresDeEmpresasAux.forEach(e -> nombresDeEmpresas.add(e));

    }

    public void hashSetContainsFirstElement()
    {
        List<String> nombresDeEmpresasAux = empresas.stream()
                .map(e -> e.getName()).collect(Collectors.toList()) ;

        System.out.printf("Contiene el hash de empresas el nombre %s? : %s\n", 
                nombresDeEmpresasAux.get(0),nombresDeEmpresas
                .contains( nombresDeEmpresasAux.indexOf(0) ) );
        System.out.println();
    }

    public void imprimirHashNombresEmpresas()
    {
        nombresDeEmpresas.forEach(System.out::println);
    }

    public void imprimirListEmpresas()
    {
        empresas.forEach(e -> System.out.println( e.getName() ) ) ;
    }
}

The thing is that when I run

public void hashSetContainsFirstElement()
        {
            List<String> nombresDeEmpresasAux = empresas.stream()
                    .map(e -> e.getName()).collect(Collectors.toList()) ;

            System.out.printf("Contiene el hash de empresas el nombre %s? : %s\n", 
                    nombresDeEmpresasAux.get(0),nombresDeEmpresas
                    .contains( nombresDeEmpresasAux.indexOf(0) ) );
        }

it prints false, which doesn't make any sense, actually the output of the program is...

    Imprimiendo lista de empresas
Nike
Facebook
Dolce&Gabbana
Twitter
Snapchat
YouTube

Contiene el hash de empresas el nombre Nike? : false

imprimiendo hash...
Nike
Dolce&Gabbana
Twitter
Facebook
YouTube
Snapchat

Which clearly shows that the HashSet nombresDeEmpresas, actually contains the name 'Nike'... why is this error happening and how can I fix it?

MoeBoeMe
  • 133
  • 1
  • 8
  • 1
    The line `.contains( nombresDeEmpresasAux.indexOf(0) ) )` is wrong, it should be `.contains( nombresDeEmpresasAux.get(0) ) )`. Your line is searching for the position of the entry `0` in the list `nombresDeEmpresasAux` (which will be -1, since your list does not contain `0`), and then asks whether the set contains `-1`, which is false – Thomas Kläger Oct 03 '17 at 04:37

1 Answers1

1

In your line:

System.out.printf("Contiene el hash de empresas el nombre %s? : %s\n", 
            nombresDeEmpresasAux.get(0),nombresDeEmpresas
            .contains( nombresDeEmpresasAux.indexOf(0) ) );

Do you want to use nombresDeEmpresasAux.get(0) instead of nombresDeEmpresasAux.indexOf(0)?

MiguelKVidal
  • 1,498
  • 1
  • 15
  • 23
  • 1
    This is sad for a typed language. `contains` takes any kind of `Object` and just returns `false` at runtime if the component type does not match. Would be nice to get a compile-time typecheck error for this. – Thilo Oct 03 '17 at 04:44
  • You are right @Thilo, but remember `List>` is generic and you have something called `type erasure` (https://docs.oracle.com/javase/tutorial/java/generics/erasure.html). There's lots of materials here on SO. Also, take a look at this question: https://stackoverflow.com/questions/2642589/how-does-a-arraylists-contains-method-evaluate-objects. Have my answer helped you solve your problem? – MiguelKVidal Oct 03 '17 at 04:50
  • That is what I am saying. A typed language can solve this at compile-time. Just like you get a compiler error when you do `nombresDeEmpresasAux.add(0)` you could also get a compiler error when you do `nombresDeEmpresasAux.indexOf(0)`. – Thilo Oct 03 '17 at 05:48
  • 1
    @Thilo take a look at those 2 questions: https://stackoverflow.com/questions/22836589/why-list-contains-takes-object-as-an-argument-in-collections-java https://stackoverflow.com/questions/104799/why-arent-java-collections-remove-methods-generic – MiguelKVidal Oct 03 '17 at 14:36