如果我的价值"foo"
,以及HashMap<String> ftw
对于其ftw.containsValue("foo")
返回true
,我怎么能得到相应的钥匙?我是否必须遍历hashmap?最好的方法是什么?
哈希表可以实现O(1)似乎是常识,但这对我来说从来没有意义.有人可以解释一下吗?以下是两种情况:
答: 该值是一个小于哈希表大小的int.因此,该值是它自己的哈希值,因此没有哈希表.但如果有,那将是O(1)并且仍然是低效的.
B. 您必须计算值的哈希值.在这种情况下,查找数据大小的顺序为O(n).在你做O(n)工作之后,查找可能是O(1),但在我眼中仍然是O(n).
除非你有一个完美的哈希表或一个大的哈希表,否则每个桶可能有几个项目.因此,无论如何,它在某个时刻转变为一个小的线性搜索.
我认为哈希表很棒,但我没有得到O(1)的名称,除非它只是理论上的.
维基百科关于哈希表的文章始终引用常量查找时间并完全忽略哈希函数的成本.这真是一个公平的衡量标准吗?
编辑:总结我学到的东西:
这在技术上是正确的,因为哈希函数不需要使用密钥中的所有信息,因此可以是恒定时间,并且因为足够大的表可以将冲突降低到接近恒定的时间.
在实践中确实如此,因为随着时间的推移,只要选择散列函数和表大小来最小化冲突,即使这通常意味着不使用常量时间散列函数,它也只会有效.
我很想认为HashSet.contains(Object)方法在恒定时间内执行.它只是获取一个对象的哈希码,然后在哈希表中查找它.
首先,有人可以确认这是否属实?
第二,如果是真的,是否有任何冲突的风险,其中两个对象可能具有相同的哈希码,因此HashSet认为它只有两个对象时只有一个?
通过"非空",我的意思是在这个问题中包含至少一个非零字符的字符串.
作为参考,这是hashCode
实现:
1493 public int hashCode() {
1494 int h = hash;
1495 if (h == 0) {
1496 int off = offset;
1497 char val[] = value;
1498 int len = count;
1499
1500 for (int i = 0; i < len; i++) {
1501 h = 31*h + val[off++];
1502 }
1503 hash = h;
1504 }
1505 return h;
1506 }
Run Code Online (Sandbox Code Playgroud)
并且算法在文档中指定.
在发生整数溢出之前,答案很简单:它不是.但我想知道的是,由于整数溢出,非空字符串的哈希码是否可能为零?你能建一个吗?
我正在寻找的理想情况是数学演示(或链接到一个)或构造算法.
我正在学习使用套装.我的问题是:集合不包含重复项.当我们尝试插入重复项时,它不会抛出任何错误并自动删除重复项.在插入集合之前检查每个值是否存在是否是一个好习惯?或者可以执行类似下面的代码?我认为Java会在内部进行检查.contains(value)
.你怎么看?
考虑到有n个元素进入集合,两种情况下的Big O复杂度是多少?
import java.util.HashSet;
import java.util.Set;
public class DuplicateTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
Set<Integer> mySet = new HashSet<Integer>();
mySet.add(10);
mySet.add(20);
mySet.add(30);
mySet.add(40);
mySet.add(50);
mySet.add(50);
mySet.add(50);
mySet.add(50);
mySet.add(50);
mySet.add(50);
System.out.println("Contents of the Hash Set :"+mySet);
}
}
Run Code Online (Sandbox Code Playgroud) 所以我遇到了一个问题."确定字符串是否包含所有唯一字符"
所以我编写了这个解决方案,将每个字符添加到一个集合中,但如果该字符已经存在,则返回false.
private static boolean allUniqueCharacters(String s) {
Set<Character> charSet = new HashSet<Character>();
for (int i = 0; i < s.length(); i++) {
char currentChar = s.charAt(i);
if (!charSet.contains(currentChar)) {
charSet.add(currentChar);
} else {
return false;
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
根据我正在阅读的书,这是"最佳解决方案"
public static boolean isUniqueChars2(String str) {
if (str.length() > 128)
return false;
boolean[] char_set = new boolean[128];
for (int i = 0; i < str.length(); i++) {
int val = str.charAt(i);
if (char_set[val]) {
return false;
}
char_set[val] …
Run Code Online (Sandbox Code Playgroud) 我有一个List
的Map<String, Integer>
.每个Map
实例都包含productName作为键,产品价格作为值.
List<Map<String, Integer>> products = GET_ALL_PRODUCTS();
Run Code Online (Sandbox Code Playgroud)
例如,List可以包含具有以下数据的Maps:
地图1:
"prod1" : 10
"prod2" : 5
"prod3" : 2
Run Code Online (Sandbox Code Playgroud)
地图2:
"prod3" : 3
"prod4" : 6
Run Code Online (Sandbox Code Playgroud)
地图3:
"prod1" : 12
"prod4" : 8
Run Code Online (Sandbox Code Playgroud)
我需要生成一个新的Map<String, Integer>
,其中包含productName作为键,但每个产品的累计价格金额为值.那是:
新地图应包含:
"prod1" : 10+12
"prod2" : 5
"prod3" : 2+3
"prod4" : 6+8
Run Code Online (Sandbox Code Playgroud)
我最终得到了以下代码,我想知道生成这个新代码的最有效方法是什么Map
?
Map<String, Integer> cumulativeMap = new HashMap<String, Integer>();
for(int i=0; i< products.size(); i++){
Map<String, Integer> product = products.get(i);
...
}
Run Code Online (Sandbox Code Playgroud) 当Hashmap的密钥的哈希码总是相等时,Hashmap的最坏情况时间复杂度是多少.
在我的理解中:由于每个密钥都具有相同的哈希码,它将始终转到同一个桶并循环通过它来检查equals方法,因此对于get和put,时间复杂度应为O(n),我是对的吗?
我正在看这个HashMap获取/放置复杂性,但它没有回答我的问题.
另外在这里Wiki Hash Table他们说明插入的最坏情况时间复杂度是O(1)而对于得到O(n)为什么会这样呢?
我一直想知道使用列表的实际好处是什么。请注意,我的问题不是“何时使用什么”,而是如果我坚持将地图作为我的主要对象,是否对性能有任何影响
显然,如果我的目标只是致力于价值观
第一眼看不清楚我的意图后更新:我的意思是如果我只想过滤一个 [8000] 个年龄 > 30 的人的列表,我会使用一个列表......但是我可以使用地图而不是它被用来代替 - 我的问题是 - 会不会有任何性能障碍?
我也会使用列表。但是我们是否获得了任何性能提升 - 如果是 - 我怎么能自己看到它。
例如,如果我采取
List <Integer> listOfInt = new ArrayList<>(map.values());
Run Code Online (Sandbox Code Playgroud)
使用 Map 作为我的全局对象并基于它提供列表是有意义的。
我知道在 Maps 中插入或删除的键/值 O(1) 运行时但是为什么列表是我见过的大多数地方的首选。
例如,使用HashSet
,我知道获取一个已知元素通常是 O(1),但我想找出获取所有元素的时间复杂度是多少(不知道它们,所以是迭代)。
我在标准库文档中的任何地方都找不到此信息。我也看过 SwissTable,但没有成功。
它甚至可以衡量吗?我在哪里可以找到它?
我想删除数据中的重复值.我知道它经常在stackoverflow中被观察到的问题,但我的问题有点不同,因为现在我正在处理非常大的数据.因此,我必须在代码中考虑最多的执行时间.
如下面的代码片段,我做了一个简单的代码来删除重复的值.
// Suppose that the dataset is very huge so that
// multi-node resources should be necessary.
String[] data = new String[10_000_000];
HashMap<String, String> uniqueItems = new HashMap<>();
for (int i = 0; i < data.length; i++) {
if (uniqueItems.containsKey(data[i])) {
uniqueItems.remove(data[i]);
uniqueItems.put(data[i], "inserted");
} else {
uniqueItems.put(data[i], "inserted");
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我不喜欢它,因为我认为其他更好的数据结构或不同的算法可以有效地删除重复的比我的代码.
所以我想寻找更好的方法来在数据很大时快速删除重复的值.
如果您能让我知道删除重复值的最快方法,我将不胜感激.
而且,我想知道重复值的数量是否会影响性能.我的意思是如果重复值是原始数据的50%,那么最佳算法和数据结构的选择将会改变吗?如果是这样,我想找到一种在一般情况下可以取得良好性能的方法.