3

I have the following two lists:

List<Animal> AllAnimals;
List<Animal> AnimalsWithEyes;

Since there are a lot of animals in the world and there are a lot of the same animals, objects, in both lists, as many have eyes, it would be kind of cool if there were a way to optimize the memory efficiency by not having duplicate objects cluttering up the RAM.

As an additional problem, the Animals in AllAnimals are ordered alphabetically, meaning that we can't just say that the first block of indexes is animals with eyes.

Any ideas on how Java can support such behavior?

Jonny Henly
  • 4,023
  • 4
  • 26
  • 43
  • "there are a lot of same animals, objects" what does it mean? In the real world, there are no duplicates – Andrew Tobilko Aug 22 '19 at 16:13
  • Have you tried `allAnimals.stream().filter(Animal::hasEyes).collect(Collectors.toList())` (providing `Animal` has an instance method `boolean hasEyes()`)? -- A remark on your code: In Java, variables and attributes should start with a lowercase letter. – Turing85 Aug 22 '19 at 16:20
  • *"optimize the memory efficiency by not having duplicate objects cluttering up the RAM"* - Depending on how you're filling those lists, there should not be duplicate objects but rather duplicate references in the lists to the same objects. – Jonny Henly Aug 22 '19 at 16:22
  • @Andrew Tobilko By that I mean that there will be lots of animals in the list AnimalsWithEyes that will also be in the list AllAnimals –  Aug 22 '19 at 18:09
  • @Turing85 Can you expound on the working of this code? Will it only go through AllAnimals and filter for the ones that the function hasEyes applies to? To your remark, I'm aware of that but I'm working on a game engine and simultaneously using UE4 where everything is uppercase so for my convenience I transferred that idea to my engine. –  Aug 22 '19 at 18:11
  • @Jonny Henly But the references will be "sizeof(animal)" not? Thats whats bothering me... –  Aug 22 '19 at 18:12
  • 2
    @mdre `filter`, as it was presented by me, calls method `boolean hasEyes()` on every animal in the collection and filters out the ones for which `hasEyes()` returns `false` (thus my comment that `Animal` needs an instance method `boolean hasEyes()`). To the size of refernces: they are the native size of your processor, so eiter 32bit or 64 bit. – Turing85 Aug 22 '19 at 18:21
  • Okay so as far as I understand at this point you can only trade off memory for performance –  Aug 22 '19 at 19:27

1 Answers1

0

Perhaps you should consider using java.util.Set and java.util.TreeSet for natural ordering(if needed be). The Set interface specification ensures, that no two equal objects exist in a Set.

Override Animal#equals, Animal#hashcode and implements Comparable interface. For example:-

public class Animal implements Comparable<Animal>{

    private final String name;
    private final boolean hasEyes;

    public Animal(String name, boolean eyes){
        this.name = name;
        this.hasEyes = eyes;
    }

    public String getName() {
        return name;
    }

    public boolean isHasEyes() {
        return hasEyes;
    }

    @Override
    public int hashCode() {
        int hash = 5;
        hash = 29 * hash + Objects.hashCode(this.name);
        hash = 29 * hash + (this.hasEyes ? 1 : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final Animal other = (Animal) obj;
        if (this.hasEyes != other.hasEyes) {
            return false;
        }
        if (!Objects.equals(this.name, other.name)) {
            return false;
        }
        return true;
    }

    @Override
    public int compareTo(Animal o) {
        //....compareTo implementation.
    }
}

Finally "intersections" between 2 List<Animal> consolidated into a Set<Animal>.

Set<Animal> s = new TreeSet<>();
s.addAll(allAnimals);
s.addAll(animalWithEyes);

The Set#addAll implementation ensure no duplicate Animal exist.

*** Or you could use project Lombok annotations to generate equals, hashcode and Comparable implementations.

Awan Biru
  • 373
  • 2
  • 10
  • The problem is not that there are multiple copies within the same list, but multiple copies in the intersection of both lists. – Turing85 Aug 22 '19 at 16:23
  • 2
    implementing `Comparable<...>` is not necessary since OP did not say anything about ordering the list. – Turing85 Aug 22 '19 at 16:28