别紧张,这是我第一次在这个级别上使用比较器。
@SuppressWarnings({ "rawtypes", "unchecked" })
public T getObjectFromExample(T object)
{
if (!sorted)
throw new IllegalStateException();
SortedSet<T> subset = setReference.subSet(object,object);
if (subset.size() == 0)
{
clsMainProgram.DebugMessage("Returned null for "+object.getClass().getName());
return null;
}
return subset.first();
}
…是我在树集上使用的方法调用,声明如下。
setReference = Collections.synchronizedSortedSet(new TreeSet<T>(comparator));
这是比较仪
public class clsComparator implements Serializable, Comparator<infIDClass> {
private static final long serialVersionUID = -4212404170394031421L;
@Override
public int compare(infIDClass o1, infIDClass o2) {
// TODO Auto-generated method stub
int z1 = (int)o1.GetID();
int z2 = (int)o2.GetID();;
if(z1 > z2)
return 1;
return z2 <= z1 ? 0 : -1;
}
}
infidclass就是这样:
public interface infIDClass {
public int GetID();
public int SetID(int newID);
}
我传递给另一个具有相同id的对象的构造如下:
//USED ONLY FOR COMPARISONS
private Building(int bID) {
this.ID = bID;
}
传递的对象只是一个带有int id的空模板,比较器将不同的项比较到集合中的方法是将id整数从低到高排序。这背后的想法是获得一种快速有效的方法,从set引用中获取具有id的对象,而不必遍历整个对象。
出于某种原因,每当我运行getobjectfromexample时,有一半的时间它都会返回null值,而当使用tailset和hedset时,它似乎会做同样的事情。我不完全清楚它为什么要这样做,代码看起来对我来说是正确的。
我不知道为什么它会这样做,除了一些模板铸造时,发送给比较,但我不确定。
2条答案
按热度按时间hsvhsicv1#
我想问题来了
SortedSet<T> subset = setReference.subSet(object,object);
根据apisubSet
提供第一个参数(包含)到第二个参数(独占)之间的元素。所以这个电话setReference.subSet(object,object)
将始终返回空集wixjitnu2#
从你的代码我可以理解你有一个
SortedSet
(这只是一个接口)由TreeSet
(sortedset接口的实现)。我还假设您的“dummysearchobject”对象/类用于搜索集合中的匹配元素Building
“也在实施infIDClass
接口-否则您可能已经得到一个编译错误。通过在树集中指定比较器,可以确保元素在树集中按正确的顺序排序。事实上,树集正在执行基于
compare(To)
方法,因此Comparator
如javadocs中所述。这就意味着违反合同
hashcode
以及equals
方法不是这里的问题,我认为首先是出了问题(坚持这个合同是非常重要的,如果不这样做可能会导致意外和难以发现的错误-所以你可能还想检查这个)。在子集方法的javadoc的基础上:
... 返回此集合中元素范围从fromement,inclusive到toelement,exclusive的部分的视图(如果fromelement和toelement相等,则返回的集为空。)。。。
这意味着您的代码运行良好,符合文档要求。如果要检索非空子集,必须指定fromement和fromement+1。这在不动产中是很难做到的,因为我们不知道fromelement+1是什么。那么,如何从集合中找到/获取要查找的元素呢?
不幸的是,set实现没有指定任何“get”方法来直接基于索引访问任何元素。所以要从集合中找到你的元素,你可以
切换到支持这种索引访问的实现(比如hashmap或linkedhashmap),但是您的元素将不再被排序。也要记得满足于
hashcode
以及equals
合同在这种情况下!)您可以使用迭代器(如这里所解释的)或流之类的方法通过迭代集合来查找元素
编辑:备注:还执行
SortedSet.subSet
将遍历整个列表以查找匹配的元素。使用流可以这样实现:
注意:流方法使用
comparator.compare
方法(这是传递给treeset构造函数的同一个比较器实现)。正在使用比较器实现,因为hashcode
以及equals
方法没有在您的示例中实现(至少从上面的代码片段中看不出这一点)。如果您正确地实现了它们,那么equals方法可以用来对对象进行“简单”的比较。.findfirst()方法将返回可继续使用的可选对象的示例。例如(根据你上面的例子):
非常重要:比较器的实现不是错误的,也不是导致问题的原因,但它根本不是最佳的。它会阻止你的树集正确地分配和排序它的元素,让它变得非常低效。
编辑:事实上,它使您的比较器实现正确,因为它使用-1、0和1的完整范围作为返回值。但是很难阅读/理解,因此仍然建议使用下面的实现。
因此,使用比较器实现如下:
正如thomas kl所建议的ä在他的回答中,格格是一条路要走。另外,您的模型类非常简单和小如果您的实际用途更复杂,您可以考虑添加另一个属性,以便在treeset中进行更有效的存储/排序(当然,仅当它也适合您的业务用例时)。对象的可比性/唯一性应主要由业务领域驱动)。
最后但并非最不重要的一点是,您可以从下面提到的代码中找到一个完整的代码示例: