You can implement equals
and hashcode
from x
and y
positions in your Region_
object.
Change your HashMap
String key to HashMap
Integer
key, in the hashmap
key use hashcode
of your Region
_ object, in getRegion
method you can make a search directly for the hash, it is not necessary to make a for
if min and max are equivalent.
Any doubt, if you use eclipse, go to option generate hashcode & equals
. It's worth putting a breakpoint
into these methods to see how it behaves.
Follow my idea of solution, there are other approaches to search optimization, I tried not to break the compatibility of your code very much. Anything gives a touch.
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
public class BuscaGrafica {
Map<Integer, Region_> regionsHash = new HashMap<>();
void addRegion(Region_ region) {
/**
* Internamente ele vai guardar na posição de memória referente ao region.hashCode()
* XXX Tem que ter atenção com este método, pois utilizando o hashCode como chave significa
* que os elementos não poderão ser alterados, pois uma vez que eu alterar fará com
* que o hashcode não seja mais o mesmo e o elemento de perca na memória.
*/
regionsHash.put(region.hashCode(), region);
}
Region_ getRegion(vector _vector3D) {
Region_ r = new Region_(_vector3D, _vector3D);
// Otimização para procurar uma posição onde o minPos e maxPos sejam equivalentes
if (regionsHash.containsKey(r)) {
// A busca é instantânea não gera muito custo computacional
regionsHash.get(r);
} else {
/**
* Aqui não tem muito milagre, o cara vai ter que procurar na mão
* Sugestões para aprimoramento desta rotina, poderá ser utilizado uma estrutura de dados
* onde a ordenação dos elementos seja por ordem de grandeza
* sendo assim podemos utilizar um algoritmo inteligente, que não precise percorrer todos os elementos do array.
* Ficar atendo que o retorno pode ser mais de um {@link Region_}, pois pode haver mais de um elemento 3d dentro de outro ainda maior.
*/
Map<Integer, Region_> collect = regionsHash.entrySet().stream()//
.filter(element -> (element.getValue().maxPos.X >= _vector3D.X && element.getValue().maxPos.Y >= _vector3D.Y && element.getValue().maxPos.Z >= _vector3D.Z) && //
(element.getValue().minPos.X <= _vector3D.X && element.getValue().minPos.Y <= _vector3D.Y && element.getValue().minPos.Z <= _vector3D.Z))//
.collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
// XXX aqui eu retornei o primeiro registro encontrado pelo lambda, mas é bom ficar atendo que o retorno pode ser mais de um...
return collect.values().iterator().next();
}
return null;
}
public class Region_ {
public Region_(vector _minPos, vector _maxPos) {
minPos = _minPos;
maxPos = _maxPos;
}
vector minPos;
vector maxPos;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + ((maxPos == null) ? 0 : maxPos.hashCode());
result = prime * result + ((minPos == null) ? 0 : minPos.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
Region_ other = (Region_) obj;
if (!getOuterType().equals(other.getOuterType())) return false;
if (maxPos == null) {
if (other.maxPos != null) return false;
} else if (!maxPos.equals(other.maxPos)) return false;
if (minPos == null) {
if (other.minPos != null) return false;
} else if (!minPos.equals(other.minPos)) return false;
return true;
}
private BuscaGrafica getOuterType() {
return BuscaGrafica.this;
}
}
class vector {
vector(int _X, int _Y, int _Z) {
X = _X;
Y = _Y;
Z = _Z;
}
int X, Y, Z;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + getOuterType().hashCode();
result = prime * result + X;
result = prime * result + Y;
result = prime * result + Z;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
vector other = (vector) obj;
if (!getOuterType().equals(other.getOuterType())) return false;
if (X != other.X) return false;
if (Y != other.Y) return false;
if (Z != other.Z) return false;
return true;
}
private BuscaGrafica getOuterType() {
return BuscaGrafica.this;
}
}
}