Siguiendo un poco con la temática de la Collection
framework, este es un topic muy interesante, como ya sabemos hay varias interfaces en este framework, el HashSet
es una de las implementaciones de la SetForma parte de la Collection
framework y básicamente lo que quiere decir es que en un Set solo puede existir un objeto, no pueden haber objetos repetidos.
interface. Para crear un HashSet
solo tenemos que hacerlo de esta manera:
// Un HashSet simple de String
HashSet<String> hashSet = new HashSet<String>();
Simple no, bueno detrás de ese código, si vamos un poco más allá podemos ver que el código de ese constructor es así:
public HashSet() {
map = new HashMap<>();
}
//Donde "map" esta declarado asi
HashMap<E,Object> map;
Aquí ya vemos que algo está un poco extraño, sorpresa, como es que un HashSet
que implementa la interface Set
en su implementación tiene un HashMap
que implementa la interface Map
?? Bueno algo muy sencillo, como les venía diciendo al principio del articulo un HashSet
no permite objetos repetidos y los ingenieros de Java para asegurarse de que no pudiéramos ingresar objetos repetidos decidió utilizar un HashMap
internamente el cual tampoco permite objetos repetidos, por que lo hicieron así?? Porque pueden, es algo confuso, pero funciona muy bien y reutilizan el código.
Deberías leer: Que es un HashMap y como funciona.
Una vez creado el HashSet
, vamos a comentar un poco sus métodos mas importantes, supongamos que queremos agregar un conjuntos de personas al HashSet
, lo hacemos así:
hashSet.add("Pedro");
hashSet.add("Pepe");
hashSet.add("Luis");
System.out.println("HashSet= " + hashSet);
Si corremos el ejemplo veremos la salida en la consola:
HashSet= [Pedro, Pepe, Luis]
Si analizamos el método add()
, vemos que este es su código:
public boolean add(E e) {
return map.put(e, PRESENT)==null;
}
// Donde "PRESENT" es
Object PRESENT = new Object();
Este método devuelve un boolean
, si el objeto se agrega al HashSet
devuelve true
si no false
, como ya sabemos, internamente esto funciona como un HashMap
, cuando agregamos un objeto en un HashMap
si ese objeto ya está agregado devuelve el valor anterior de esa key pero si el objeto no está y se agrega al HashMap
devuelve null, entonces lo que hace el método add()
es evaluar que devuelve y así se sabe si agrega o no el objeto. Podemos utilizar el boolean
que devuelve el método para ejecutar algún código, por ejemplo:
boolean b = hashSet.add("Luis");
if(b){
// Se agrego correctamente
// code
}else{
// Ya esta en el HashSet
// code
}
Como ya "Luis" está en el HashSet
el metodo add()
devuelve false
y podríamos hacer algo en ese caso.
Si necesitamos eliminar un objeto del HashSet
lo hacemos así:
hashSet.remove("Luis");
// Codigo del metodo remove()
public boolean remove(Object o) {
return map.remove(o)==PRESENT;
}
La misma teoría del método add()
.
Como obtener un objeto del HashSet
? Si estás acostumbrado a utilizar ArrayList
, HashMap
, Arrays
puedes asumir que también se puede obtener un determinado objeto de un HashSet
y no es así, el HashSet
no posee un método para obtener un determinado objeto. Según mi punto de vista esto no es que este mal porque puedes resolverlo de varias maneras, en realidad no es necesario un metodo get()
, de la manera más sencilla desde mi punto de vista sería así:
if(hashSet.contains("Pepe")){
// Se supone que si esta el objeto y podriamos sustituir el metodo get()
// code
}
Preguntando si un determinado objeto está en el HashSet
podríamos sustituir el método get()
ya que asumiríamos que el objeto si esta. También podemos iterar el HashSet
de esta manera:
for (Iterator<String> iterator = hashSet.iterator(); iterator.hasNext();) {
String nombre = iterator.next();
if (nombre.equals("Pedro")){
// code
}
}
Esta manera también es válida pero gasta más recursos en comparación con el método contains()
. Otra manera puede ser pasando el HashSet a un ArrayList:
ArrayList<String> arrayList = new ArrayList<String>(hashSet);
String nombre = arrayList.get(2);
También es válida pero sigo quedándome con la primera opción.
Caracteristicas del HashSet
:
- Solo almacena objetos.
- No permite objetos duplicados.
- Solo permite un objeto
null
- Implementa la
Set
interface.
- No garantiza ningún tipo de orden al insertar los objetos.
- Es un wrapper de
HashMap
.
Ese es básicamente el funcionamiento del HashSet
, tienes que ver dependiendo de la necesidad que componente utilizar, ya eso queda de tu parte pero te recomiendo que utilices HashSet
si no quieres almacenar objetos repetidos, si eso no importa deberías utilizar HashMap
ya que el HashSet
es solo un wrapperUna clase wrapper es una clase que encapsula tipos de datos, de modo que esos tipos de datos pueden utilizarte para crear instancias en otra clase que necesita los mismos, en este caso HashSet utiliza internamente HashMap
.
de HashMap
. Recuerda comentar si necesitas que agregue algo más a esta entrada o si tienes alguna duda.
Suerte!!