- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在对 "How to implement List, Set, and Map in null free design?" 的评论中, Steven Sudit我开始讨论使用回调,处理“找到”和“未找到”情况,与 tryGet()
方法,采用 out
参数并返回一个 boolean 值,指示是否已填充 out 参数。 Steven 坚持认为回调方法更复杂,而且几乎肯定会更慢。我坚持认为复杂性并没有更大,最坏的表现也是一样的。
但是代码胜于 Eloquent ,所以我想我会同时实现两者,看看我得到了什么。最初的问题是关于语言的相当理论性的(“为了论证起见,假设这种语言甚至没有 null
”)——我在这里使用了 Java,因为那是我得心应手的。 Java 没有 out 参数,但它也没有一流的函数,所以从风格上讲,这两种方法应该同样糟糕。
(题外话:就复杂性而言:我喜欢回调设计,因为它固有地强制 API 的用户处理这两种情况,而 tryGet()
设计要求调用者执行他们自己的样板条件检查,他们可能会忘记或得到错了。但是现在两者都实现了,我明白为什么 tryGet()
设计看起来更简单,至少在短期内是这样。)
一、回调示例:
class CallbackMap<K, V> {
private final Map<K, V> backingMap;
public CallbackMap(Map<K, V> backingMap) {
this.backingMap = backingMap;
}
void lookup(K key, Callback<K, V> handler) {
V val = backingMap.get(key);
if (val == null) {
handler.handleMissing(key);
} else {
handler.handleFound(key, val);
}
}
}
interface Callback<K, V> {
void handleFound(K key, V value);
void handleMissing(K key);
}
class CallbackExample {
private final Map<String, String> map;
private final List<String> found;
private final List<String> missing;
private Callback<String, String> handler;
public CallbackExample(Map<String, String> map) {
this.map = map;
found = new ArrayList<String>(map.size());
missing = new ArrayList<String>(map.size());
handler = new Callback<String, String>() {
public void handleFound(String key, String value) {
found.add(key + ": " + value);
}
public void handleMissing(String key) {
missing.add(key);
}
};
}
void test() {
CallbackMap<String, String> cbMap = new CallbackMap<String, String>(map);
for (int i = 0, count = map.size(); i < count; i++) {
String key = "key" + i;
cbMap.lookup(key, handler);
}
System.out.println(found.size() + " found");
System.out.println(missing.size() + " missing");
}
}
tryGet()
示例——据我所知,这种模式(我很可能是错的):
class TryGetMap<K, V> {
private final Map<K, V> backingMap;
public TryGetMap(Map<K, V> backingMap) {
this.backingMap = backingMap;
}
boolean tryGet(K key, OutParameter<V> valueParam) {
V val = backingMap.get(key);
if (val == null) {
return false;
}
valueParam.value = val;
return true;
}
}
class OutParameter<V> {
V value;
}
class TryGetExample {
private final Map<String, String> map;
private final List<String> found;
private final List<String> missing;
private final OutParameter<String> out = new OutParameter<String>();
public TryGetExample(Map<String, String> map) {
this.map = map;
found = new ArrayList<String>(map.size());
missing = new ArrayList<String>(map.size());
}
void test() {
TryGetMap<String, String> tgMap = new TryGetMap<String, String>(map);
for (int i = 0, count = map.size(); i < count; i++) {
String key = "key" + i;
if (tgMap.tryGet(key, out)) {
found.add(key + ": " + out.value);
} else {
missing.add(key);
}
}
System.out.println(found.size() + " found");
System.out.println(missing.size() + " missing");
}
}
public static void main(String[] args) {
int size = 200000;
Map<String, String> map = new HashMap<String, String>();
for (int i = 0; i < size; i++) {
String val = (i % 5 == 0) ? null : "value" + i;
map.put("key" + i, val);
}
long totalCallback = 0;
long totalTryGet = 0;
int iterations = 20;
for (int i = 0; i < iterations; i++) {
{
TryGetExample tryGet = new TryGetExample(map);
long tryGetStart = System.currentTimeMillis();
tryGet.test();
totalTryGet += (System.currentTimeMillis() - tryGetStart);
}
System.gc();
{
CallbackExample callback = new CallbackExample(map);
long callbackStart = System.currentTimeMillis();
callback.test();
totalCallback += (System.currentTimeMillis() - callbackStart);
}
System.gc();
}
System.out.println("Avg. callback: " + (totalCallback / iterations));
System.out.println("Avg. tryGet(): " + (totalTryGet / iterations));
}
tryGet()
低 50%。 ,这真的让我很惊讶。但是,凭直觉,我添加了一些垃圾收集,性能损失消失了。
tryGet()
执行。想法?
TryGetExample
重复使用
OutParameter
.
最佳答案
我想说,无论性能如何,这两种设计在实践中都没有意义。我认为这两种机制都过于复杂,更重要的是,没有考虑到实际使用情况。
实际使用情况
如果用户在 map 中查找某个值但该值不存在,则该用户很可能需要以下内容之一:
has(key)
这表明 key 是否存在(如果只想检查 key 是否存在)。 get(key)
如果存在键,则报告值;否则,抛出 NoSuchElementException。 get(key,defaultval)
它报告键的值,如果键不存在,则返回 defaultval。 setdefault(key,defaultval)
如果 key 不存在,则插入 (key,defaultval),并返回与 key 关联的值(如果没有先前的映射,则为 defaultval,否则为 prev 映射)。 关于java - 无空 "maps": Is a callback solution slower than tryGet()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2681415/
我是一名优秀的程序员,十分优秀!