Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/305.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;到Java:高效地搜索集合 P>来自一个主要C++背景,我现在正在愤怒中编写一些java。我觉得C++中使用STL的基本内容似乎比java更麻烦。我的结论是,可能有一个更好的Java习惯用法我还不知道。下面是一个使用伪代码的示例_Java_C++_Collections_Map_Set - Fatal编程技术网

C++;到Java:高效地搜索集合 P>来自一个主要C++背景,我现在正在愤怒中编写一些java。我觉得C++中使用STL的基本内容似乎比java更麻烦。我的结论是,可能有一个更好的Java习惯用法我还不知道。下面是一个使用伪代码的示例

C++;到Java:高效地搜索集合 P>来自一个主要C++背景,我现在正在愤怒中编写一些java。我觉得C++中使用STL的基本内容似乎比java更麻烦。我的结论是,可能有一个更好的Java习惯用法我还不知道。下面是一个使用伪代码的示例,java,c++,collections,map,set,Java,C++,Collections,Map,Set,我有一个集合,它有一个基于一些成员变量的自然排序关系,这些成员变量恰好是字符串 class Thing { String key1; String key2; } 在C++中,我可以定义一个排序运算符< P> java方式来做这是,是的,使用 map < /C> > 从C++的背景来看,这似乎不必要地膨胀。既然东西已经包含了密钥,为什么还要再次存储它 这并不像你想象的那么多开销。您正在存储对字符串的一个额外引用,总开销为…4字节。(实际上,成本为零:TreeSet实现占用的内存与T

我有一个集合,它有一个基于一些成员变量的自然排序关系,这些成员变量恰好是字符串

class Thing
{
   String key1;
   String key2;
}

<>在C++中,我可以定义一个排序运算符< P> java方式来做这是,是的,使用<代码> map < /C> > 从C++的背景来看,这似乎不必要地膨胀。既然东西已经包含了密钥,为什么还要再次存储它

这并不像你想象的那么多开销。您正在存储对
字符串的一个额外引用,总开销为…4字节。(实际上,成本为零:
TreeSet
实现占用的内存与
TreeMap
占用的内存完全相同)


如果要使用两个键进行搜索,可以使用比较两个键的
比较器
,或使
东西
实现
可比
,然后维护
树集
。这比您上面编写的…不愉快的
比较器
要紧凑得多。如果您想用一键搜索,只需使用
地图
。如果你真的,真的想用这两个来搜索,那么就同时维护它们。(实际上,我几乎从来没有这样做过……JDK Collections框架的作者也不认为您需要经常这样做。)

问题还不错,但我不明白您是如何使用
std::set
在O(logn)时间内搜索不同的键的
std::set
仅使用1个比较器类,并且只比较集合的
值类型
,因此在使用
find()
下限()
上限()
时,额外的重载将没有帮助。如果您使用的是
std::find()
,则会陷入线性搜索。在一个集合中使用
std::find
,会浪费时间
std::set
O(logn)
,而set上的
std::find
将是
O(N)
(在操作总数中,即使比较的数量仍然是
O(logn)
),如果codea.key1>b.key1
,则
操作符的
实现会导致未定义的行为,因为它不会返回该情况下的值。我的措辞选择不当(实际上完全错误)。事实上,我正在使用std::lower_bound和多个比较方法,如果我使用find,它将被设置为::find或map::find,而不是std::find。在本例中,集合只有一个总顺序,但您可能希望以几种方式与之匹配。我将编辑以更好地解释和更正运算符<定义。我想我对这个问题的两个方面感到好奇。当Java社区真的需要编写高效的代码时,他们倾向于如何思考,他们会做什么。例如,我可以使用一个排序向量而不是一个STD::设置在C++中,完全失去树,而代价是插入更昂贵。通过使用ArrayList和Collections.sort,我可以在Java中实现同样的功能。Java人员可能会在ApacheCommons中找到更合适的东西,而不是自己的。集合框架本身倾向于推动您使用一致的抽象。例如,“排序的
列表
”将无法满足
add(int,E)
的约定,该约定指定在特定位置添加元素。也就是说,我从来没有发现这会严重影响性能,而且JDK中的实现通常比您或我编写的任何东西都要好。四处搜索我怀疑您在Guava中的iterables接口更适合我的编程风格。所以看起来,在这种情况下,JDK中的实现并不比您编写的任何东西(例如,在google)都好——我想我需要问自己一个不同的问题,我应该使用哪些库以及为什么。我还问自己,为什么还有一个apache commons collections库。老实说,没有一个链接问题的答案——甚至是使用Guava的答案——比直接的for循环表现得更好,老实说,我认为大多数答案都不那么可读。(例如,参见Guava wiki的页面。)值得注意的是,Guava紧随Apache之后,解决了Commons库存在的问题,即a)Apache没有提供泛型,b)Apache库倾向于违反收集合同。我知道Guava创建的原因。不太清楚为什么首先需要Apache commons集合。从C++背景来看,番石榴的重要贡献是功能风格算法和不可变的集合,这些集合是用C++在STL中提供的。
///
/// @brief
/// provide a total order for 'Things' using key1 and key2
///
bool operator<(const Thing& a, const Thing& b)
{
  if (a.key1 < b.key1) return true; 
  else if (a.key1 > b.key1) return false; 
  else return a.key2 < b.key2;
} 
struct Ordering
{
   /// A strict weak ordering not a total ordering
   bool operator()(const Thing& A,const std::string& key1) const;
}

const_iterator iter = std::lower_bound(someThings.begin(),
                                       someThings.end(),
                                       key1,
                                       Ordering());
public static class Order implements Comparator<Object>
{
  @Override
  @Constant
  public int compare(Object a, Object b)
  {
     String aString;
     String bString;         
     if (a instanceof String)
     {
        aString = (String)a;
     }
     else if (a instanceof Thing)
     {
        aString = ((Field)a).getKey1();
     }
     else
     {
        throw new ClassCastException("String or Field object expected.");
     }
     if (b instanceof String)
     {
        bString = (String)b;
     }
     else if (b instanceof Thing)
     {
        bString = ((Field)b).getKey1();
     }
     else
     {
        throw new ClassCastException("String or Field object expected.");
     }
     return aString.compareTo(bString);
  }
};
Set<Thing> things = new TreeSet<Thing>(new Order());

boolean hasFieldWithKey1(final String key1) 
{
   return this.fields.contains(key1);
}
Field getFieldWithKey1(final String key1) 
{
   return this.fields.floor(key1);
}
Map<String,Thing> thingsByKey1 = new TreeMap<Thing>(new Order());
Map<String,Thing> thingsByKey1 = new TreeMap<Thing>(new OrderByKey1());
Map<String,Thing> thingsByKey2 = new TreeMap<Thing>(new OrderByKey2());