使用Java';s包含用于集合(例如HashSet)的(对象)方法,而实际上没有对象
我承认这听起来有点疯狂,但要解释一下我的意思: 我有一个使用Java';s包含用于集合(例如HashSet)的(对象)方法,而实际上没有对象,java,collections,map,contains,hashset,Java,Collections,Map,Contains,Hashset,我承认这听起来有点疯狂,但要解释一下我的意思: 我有一个集合(例如HashSet),其中包含几个非常慢的初始化对象,我想看看集合是否已经包含一个特定的对象。让我们以Vector3d为例(我知道初始化并不昂贵) 因此,集合包含: Vector3d(1,1,1) Vector3d(2,1,1) Vector3d(3,1,1) 我想问集合这个问题,“集合是否包含一个Vector3d,其中x=2,y=1和z=1(即我已经知道包含的()方法将散列的数据),因此我可以创建一个新的Vector3d(2,1,
集合
(例如HashSet),其中包含几个非常慢的初始化对象,我想看看集合
是否已经包含一个特定的对象。让我们以Vector3d
为例(我知道初始化并不昂贵)
因此,集合
包含:
Vector3d(1,1,1)
Vector3d(2,1,1)
Vector3d(3,1,1)
我想问集合
这个问题,“集合是否包含一个Vector3d
,其中x=2
,y=1
和z=1
(即我已经知道包含的()
方法将散列的数据),因此我可以创建一个新的Vector3d(2,1,1)
然后在上面使用.contains()
,但正如我所说的,对象初始化速度很慢,或者我可以运行整个集合
手动检查(这就是我现在正在做的),但是(据我所知)比.contains()
慢,因为它不使用哈希。有更好的方法吗
所讨论的对象是可变的,但是
等于方法所基于的数据是不可变的。(在我的情况下,它们是x、y、z坐标处的块,块的内容可能会改变,但x、y、z坐标不会改变)contains方法将调用对象的.equals方法,因此只要该类的.equals实现比较对象中包含的值而不是它们的指针,那么使用contains就会起作用
编辑有点误读了您的问题。我认为这取决于列表的大小和初始化所需的时间。如果列表很短,请迭代列表并手动检查。但是如果列表可能很长,则创建对象并使用.contains可能会更有效。contains方法将调用对象的.equals方法,只要该类的.equals实现比较对象中包含的值而不是它们的指针,那么使用contains就可以了
编辑有点误读了你的问题。我认为这取决于列表的大小和初始化所需的时间。如果列表很短,请迭代列表并手动检查。但是如果列表可能很长,则创建对象和使用.contains可能更有效。ArrayList.contains
不使用散列;它与手动检查的速度完全相同。这两种方式都没有区别
使用伪对象类是可行的,但几乎可以肯定会有代码味道。ArrayList.contains
不使用哈希;它与手动检查的速度完全相同。这两种方法都没有区别
使用伪对象类是可行的,但几乎肯定会有代码气味。在ArrayList
上使用.contains()
方法将导致对ArrayList
中的每个实例调用equals
方法
虽然这对您很有用,但对于非常大的数组列表
可能没有好处。如果性能有问题,您可能希望持有一个哈希集
,其中包含对Vector3d
对象的引用。在哈希集
(或任何哈希集
)上调用包含
非常快。在ArrayList
上使用.contains()
方法将导致对ArrayList
中的每个实例调用equals
方法
虽然这对您很有用,但对于非常大的数组列表
可能没有好处。如果性能有问题,您可能希望持有一个哈希集
,其中包含对Vector3d
对象的引用。在哈希集
(或任何哈希集
)上调用包含
速度大大加快。如果你真的需要使用列表(而不是散列),你不妨在列表上迭代,检索每个对象并手动检查其属性——我的意思是,这与“包含”一样快
如果要使用哈希而不是列表,则应使用不同的对象进行比较。例如,如果将哈希映射用于上述示例,则键可以是以下字符串:
“1,1,1”、“2,1,1”、“3,1,1”
这将使查找变得即时和简单。如果列表可以包含其他类型的对象,那么“Vector3d(1,1,1)”可能是一个更好的字符串。它可以轻松地重新创建,而不需要昂贵的费用或增加代码复杂性
如果您使用列表是因为需要保留顺序,请查看LinkedHashMap
另外,我建议您创建一个函数,从对象(插入时)或参数(搜索时)派生字符串,而不是在代码周围分发功能,这是您以后可能需要更改或扩展的内容。如果您确实需要使用列表(而不是散列)您还可以迭代列表,检索每个对象并手动检查其属性——我的意思是,这与“Contains”一样快
如果要使用哈希而不是列表,则应使用不同的对象进行比较。例如,如果将哈希映射用于上述示例,则键可以是以下字符串:
“1,1,1”、“2,1,1”、“3,1,1”
这将使查找变得即时和简单。如果列表可以包含其他类型的对象,那么“Vector3d(1,1,1)”可能是一个更好的字符串。它可以轻松地重新创建,而不需要昂贵的费用或增加代码复杂性
如果您使用列表是因为需要保留顺序,请查看LinkedHashMap
我还建议您创建一个函数,从对象(插入时)或参数(插入时)派生字符串
package mygame;
import java.util.HashMap;
import java.util.Map;
public class Main{
public Main(){
Map<CheapKey,ExpensiveClass> map=new HashMap< CheapKey, ExpensiveClass>();
for(int i=0;i<100;i++){
ExpensiveClass newExpensiveClass;
newExpensiveClass=new ExpensiveClass(i,0,0);
map.put(newExpensiveClass.getKey(), newExpensiveClass);
}
CheapKey testKey1=new CheapKey(1,0,0);
CheapKey testKey2=new CheapKey(1,0,1);
System.out.println(map.containsKey(testKey1)); //there is an object under key1
System.out.println(map.containsKey(testKey2)); //there isn't an object under key2
ExpensiveClass retrievedExpensiveClass=map.get(testKey1);
}
public static void main(String[] args) {
Main main=new Main();
}
protected class ExpensiveClass{
int x;
int y;
int z;
public ExpensiveClass(int x, int y, int z){
this.x=x;
this.y=y;
this.z=z;
for(int i=0;i<10000;i++){
//slow initilisation
}
}
public CheapKey getKey(){
return new CheapKey(x,y,z);
}
}
protected class CheapKey{
int x;
int y;
int z;
public CheapKey(int x, int y, int z){
this.x=x;
this.y=y;
this.z=z;
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final CheapKey other = (CheapKey) obj;
return true;
}
@Override
public int hashCode() {
int hash = 7;
hash = 79 * hash + this.x;
hash = 79 * hash + this.y;
hash = 79 * hash + this.z;
return hash;
}
}
}