Hot questions for Operating HashSet in Guava

Top 10 Java Open Source / Guava / Operating HashSet

Thread-safe HashSet with Guava Collections

Question: Like the title says, i would like to get a thread-safe HashSet using Guava Collections.

Can you help me?

Answer: Using the Sets class from Guava

Set<K> set = Collections.newSetFromMap(new ConcurrentHashMap<K, Boolean>());

how to insert into set without changing the equals and hashcode

Question: I'm looking for a suggestion. I have a Person class with String firstName and String lastName When i'm tying to insert the list values with the same String like :

set.add(new Person("firstName","lastName"))

set.add(new Person("firstName","lastName"))

The set doesn`t filter the objects and they still getting in the set. There is any suggestion to create set list without overriding the equales and hashcode functions? Maybe with guava or some groovy list?

Answer: In Guava there's an Equivalence class designed to such things. Create your own Equivalence class like this one:

public class PersonEquivalence extends Equivalence<Person> {

  @Override
  protected boolean doEquivalent(Person p1, Person p2) {
    return Objects.equal(p1.getFistName(), p2.getFistName())
        && Objects.equal(p1.getLastName(), p2.getLastName());
  }

  @Override
  protected int doHash(Person person) {
    return Objects.hashCode(person.getFistName(), person.getLastName());
  }

}

And then this code

Set<Equivalence.Wrapper<Person>> set = Sets.newHashSet();
PersonEquivalence personEquivalence = new PersonEquivalence();
set.add(personEquivalence.wrap(new Person("Joe", "Doe")));
set.add(personEquivalence.wrap(new Person("Joe", "Doe")));
set.add(personEquivalence.wrap(new Person("Jane", "Doe")));
System.out.println(set);

prints

[PersonEquivalence@8813f2.wrap(Person{firstName=Jane, lastName=Doe}),
 PersonEquivalence@8813f2.wrap(Person{firstName=Joe, lastName=Doe})]

Of course it's a bit verbose, but you can create ForwardingSet to automatically wrap and unwrap Persons for you.


Text file into Java Set<String> using Commons or Guava

Question: I would like to load each line in a file into HashSet collection. Is there a simple way to do this?

Answer: using Guava

Sets.newHashSet(Files.readLines(file, charSet));

Using the Apache Commons FileUtils class and the readlines method.

Set<String> lines = new HashSet<String>(FileUtils.readLines(File, Charset));

Java/Kotlin: Finding the intersection of multiple HashSets by class ID

Question: I'm having trouble finding the intersection of an Array of Hashed Sets that contain a data Class (where I want to intersect by identifier):

class Protein(val id: String, val score: Double, val molw: Double, val spc: Int)

I've pulled in some data from a .csv file into this type of structure:

ArrayList<HashSet<Protein>>

So I have six array lists [1 for each csv], each containing one hashed set that contains thousands of Protein structures. Here's what I've tried so far to get an intersection HashSet based off of common Protein.id:

fun intersection(data: ArrayList<HashSet<Protein>>): HashSet<Protein> {

val intersectionSet = HashSet<Protein>(data[0])

for (i in 1..data.size) {
    intersectionSet.retainAll(data[i])
}
return intersectionSet
}

This returns an empty list, which makes sense given that it's trying to intersect Protein objects and match each criteria as a whole.

How do I call data[i].id as my intersection criteria? I'm fairly new to Kotlin and data classes.

Answer: If you add definitions for the hashCode and equals function in the Protein class as follows, then the HashSet will be able to appropriately check the intersection using the id field.

class Protein(val id: String, val score: Double, val molw: Double, val spc: Int) {
  override fun hashCode() = id.hashCode()
  override fun equals(other: Any?) = other?.let { id == (it as Protein).id } ?: false
}

Also you probably want to change the range in your loop within the intersection function to be 1..(data.size-1) instead of 1..data.size to avoid going out of bounds. Alternatively you could write it functionally as follows:

fun intersection(data: ArrayList<HashSet<Protein>>): HashSet<Protein> {
  return data.reduce { acc, it -> acc.apply { retainAll(it) } }
}