问题的标题可能会给你一个重复问题的印象,但根据我的说法不是。
我只是几个月的Java和一个月的MongoDB,SpringBoot和REST。
我有一个包含3个字段的Mongo Collection, _id(默认字段),appName和appKey 。我正在使用 list 来遍历所有文档,并找到一个appName和appKey与传递的文档匹配的文档。这个集合现在只有4个条目,因此它运行顺利。但我正在阅读有关集合的内容,发现如果集合中的文档数量较多,则 list 的结果将比 hashMap 慢得多。< / p>
但正如我已经说过我对Java很新,我在将代码转换为 hashMap 时遇到了一些麻烦,所以我希望有人可以指导我完成这个。< / p>
我也附上我的代码供参考。
public List<Document> fetchData() {
// Collection that stores appName and appKey
MongoCollection<Document> collection = db.getCollection("info");
List<Document> nameAndKeyList = new ArrayList<Document>();
// Getting the list of appName and appKey from info DB
AggregateIterable<Document> output = collection
.aggregate(Arrays.asList(new BasicDBObject("$group", new BasicDBObject("_id",
new BasicDBObject("_id", "$id").append("appName", "$appName").append("appKey", "$appKey"))
)));
for (Document doc : output) {
nameAndKeyList.add((Document) doc.get("_id"));
}
return nameAndKeyList;
}// End of Method
然后我在同一个类的另一个方法中调用它:
List<Document> nameAndKeyList = new ArrayList<>();
//InfoController is the name of the class
InfoController obj1 = new InfoController();
nameAndKeyList = obj1.fetchData();
// Fetching and checking if the appName & appKey pair
// is present in the DB one by one.
// If appName & appKey mismatches, it increments the value
// of 'i' and check them with the other values in DB
for (int i = 0; i < nameAndKeyList.size(); i++) {
"followed by my code"
如果我没有错,那么也不需要上述循环。
提前致谢。
答案 0 :(得分:2)
您只需要一个简单的查找查询即可直接从Mongo DB获取所需的记录。
Document document = collection
.find(new Document("appName", someappname).append("appKey", someappkey)).first();
答案 1 :(得分:1)
首先,列表并不比HashMap慢或快。 Hasmap通常用于保存密钥对值,例如&#34; ID&#34;,&#34; Name&#34;或类似的东西。在您的情况下,我看到您正在使用没有指定大小的ArrayList列表。当你不知道大小时更好地使用链表,因为arraylist后面有一个数组并通过复制扩展它。如果要从列表中生成Hasmap或使用Hasmap,则需要将ID和值映射到记录。
HashMap<String /*type of the identifier*/, String /*type of value*/> map = new HashMap<String,String>();
for (Document doc : output) {
map.put(doc.get("_id"), doc.get("_value"));
}
答案 2 :(得分:1)
首先,避免过早优化(如果您不知道它是什么,请查找表达式)。在列表中放置包含近实际数据的数千个项目。尝试检索不存在的项目。这将强制您的HashMap
循环遍历整个列表。看看需要多长时间。尝试多次以获得您是否感到不耐烦的印象。如果你不这样做,那就完成了。
如果您发现需要加速,我同意HashMap
是尝试的明显解决方案之一。首先要考虑的事情之一是appName
的关键类型。据我了解,您需要搜索的内容是appKey
和equals
都正确的项目。好的解决方案是用这两个字段和hashCode
和DocumentHashMapKey
方法编写一个简单的类(我现在称之为hashCode()
,想一个更好的名字)。对于Objects.hash(appName, appKey)
,请尝试HashMap< DocumentHashMapKey, Document>
。如果您的数据不能令人满意,请考虑替代方案。现在您已准备好构建HashMap
。
如果你是懒惰或者只是想要了解appName + "$@@" + appKey
如何执行的第一印象,你也可以通过连接HashMap<String, Document>
来构建你的密钥(其中中间的字符串不太可能是成为名称或密钥的一部分)并使用{{1}}。
我所说的一切都可以根据您的需求进行改进。这只是为了让你开始。
答案 3 :(得分:0)
感谢大家的帮助,没有我的帮助,我就无法找到解决方案。
public HashMap<String, String> fetchData() {
// Collection that stores appName and apiKey
MongoCollection<Document> collection = db.getCollection("info");
HashMap<String, String> appKeys = new HashMap<String, String>();
// Getting the list of appName and appKey from info DB
AggregateIterable<Document> output = collection
.aggregate(Arrays.asList(new BasicDBObject("$group", new BasicDBObject("_id",
new BasicDBObject("_id", "$id").append("appName", "$appName").append("appKey", "$appKey"))
)));
String appName = null;
String appKey = null;
for (Document doc : output) {
Document temp = (Document) doc.get("_id");
appName = (String) temp.get("appName");
appKey = (String) temp.get("appKey");
appKeys.put(appName, appKey);
}
return appKeys;
将上述方法调用到同一类的另一个方法中。
InfoController obj = new InfoController();
//Fetching the values of 'appName' & 'appKey' sent from 'info' DB
HashMap<String, String> appKeys = obj.fetchData();
storedAppkey = appKeys.get(appName);
//Handling the case of mismatch
if (storedAppkey == null || storedApikey.compareTo(appKey)!=0)
{//Then the response and further processing that I need to do.
现在HashMap所做的是它使我的代码更具可读性,并且我用于迭代的'for'循环已经消失,尽管它在性能方面可能没有太大差别。
再次感谢大家的帮助和支持。