我想使用不区分大小写的字符串作为HashMap键,原因如下.
<key, value>从HashMap中找到忽略我从流量中收到的情况.我遵循了这种方法
CaseInsensitiveString.java
public final class CaseInsensitiveString {
private String s;
public CaseInsensitiveString(String s) {
if (s == null)
throw new NullPointerException();
this.s = s;
}
public boolean equals(Object o) {
return o instanceof CaseInsensitiveString &&
((CaseInsensitiveString)o).s.equalsIgnoreCase(s);
}
private volatile int hashCode = 0;
public int hashCode() {
if (hashCode == 0)
hashCode = s.toUpperCase().hashCode();
return hashCode;
}
public String toString() {
return s;
}
}
Run Code Online (Sandbox Code Playgroud)
LookupCode.java
node = nodeMap.get(new CaseInsensitiveString(stringFromEvent.toString()));
Run Code Online (Sandbox Code Playgroud)
因此,我正在为每个事件创建一个CaseInsensitiveString的新对象.因此,它可能会影响性能.
有没有其他方法可以解决这个问题?
我想知道HashMap中是否存在特定的键,所以我使用的是containsKey(key)方法.但它区分大小写,即如果有一个带有Name的键并且我正在搜索名称,则它不会返回true.那么有什么方法我可以知道没有打扰钥匙的情况?
谢谢
我遇到了一个场景,我想要小写HashMap的所有键(不要问为什么,我只需要这样做).HashMap有数百万条目.
起初,我以为我只是创建一个新的Map,迭代要小写的地图条目,并添加相应的值.这个任务应该每天只运行一次或类似的东西,所以我想我可以裸露这个.
Map<String, Long> lowerCaseMap = new HashMap<>(myMap.size());
for (Map.Entry<String, Long> entry : myMap.entrySet()) {
lowerCaseMap.put(entry.getKey().toLowerCase(), entry.getValue());
}
Run Code Online (Sandbox Code Playgroud)
但是,当我的服务器在这一次过载时,我正要复制Map时,会导致一些OutOfMemory错误.
现在我的问题是,如何以最小的内存占用来完成这项任务?
在小写后删除每个键 - 添加到新Map帮助?
我可以利用java8流来加快速度吗?(例如这样的事情)
Map<String, Long> lowerCaseMap = myMap.entrySet().parallelStream().collect(Collectors.toMap(entry -> entry.getKey().toLowerCase(), Map.Entry::getValue));
Run Code Online (Sandbox Code Playgroud)
更新
似乎它是一个Collections.unmodifiableMap所以我没有选择
在小写之后移除每个键 - 添加到新地图
随着TreeMap它的琐碎,提供自定义Comparator,从而覆盖所提供的语义Comparable添加到地图中的对象.HashMap然而,不能以这种方式控制; 提供哈希值和相等性检查的函数不能"侧载".
我怀疑设计界面并将其改装成HashMap(或新类)既简单又有用?这样的事情,除了更好的名字:
interface Hasharator<T> {
int alternativeHashCode(T t);
boolean alternativeEquals(T t1, T t2);
}
class HasharatorMap<K, V> {
HasharatorMap(Hasharator<? super K> hasharator) { ... }
}
class HasharatorSet<T> {
HasharatorSet(Hasharator<? super T> hasharator) { ... }
}
Run Code Online (Sandbox Code Playgroud)
在不区分大小写Map的问题得到了平凡解:
new HasharatorMap(String.CASE_INSENSITIVE_EQUALITY);
Run Code Online (Sandbox Code Playgroud)
这是可行的,还是你能看到这种方法的任何根本问题?
该方法是否在任何现有(非JRE)库中使用?(尝试谷歌,没有运气.)
编辑:hazzen提出的很好的解决方法,但我担心这是我试图避免的解决方法......;)
编辑:更改标题不再提及"比较器"; 我怀疑这有点令人困惑.
编辑:与业绩有关的已接受答案; 我会喜欢更具体的答案!
编辑:有一个实现; 看下面接受的答案.
编辑:改写第一句话,以更清楚地表明它是我正在进行的侧面加载(而不是排序;排序不属于HashMap).
在java.util.Map中搜索键时如何忽略区分大小写?
我想知道我们是否可以忽略这个案例来查找地图中的密钥.
Example,
Map<String, Integer> lookup = new HashMap<String, Integer>();
lookup.put("one", 1);
lookup.put("two", 2);
lookup.put("three", 3);
Run Code Online (Sandbox Code Playgroud)
用户输入可以是"ONE"或"one".在这种情况下,而不是将用户输入转换为小写.是否有任何方法可以通过任何方法忽略关键敏感?
谢谢,凯西尔
假设我有一个品牌对象列表.POJO包含一个返回字符串的getName().我想Map<String, Brand>
用String作为名称来构建一个
...但我希望密钥不区分大小写.
如何使用Java流来完成这项工作?试:
brands.stream().collect(Collectors.groupingBy(brand -> brand.getName().toLowerCase()));
Run Code Online (Sandbox Code Playgroud)
不起作用,我认为是因为我没有正确使用groupBy.