使用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;
        }


    }



}