gpt4 book ai didi

multithreading - Java 8 ConcurrentHashMap 合并与 computeIfAbsent

转载 作者:行者123 更新时间:2023-12-04 06:38:43 27 4
gpt4 key购买 nike

我正在练习 Cay S. Horstmann 所著的“Java SE 8 for the really Impatient”一书的练习。有 2 个练习要求相同算法的不同实现,一个使用 merge ,其他 computeIfAbsent .我已经使用 merge 实现了该程序但不知道如何使用 computeIfAbsent做同样的事情。在我看来 computeIfPresent会更合适,因为 merge仅当 key 存在时才有效,computeIfPresent 也是如此.

问题陈述:

Write an application in which multiple threads read all words from a collection of files. Use a ConcurrentHashMap<String, Set<File>> to track in which files each word occurs. Use the merge method to update the map.



我的代码使用 merge :
public static Map<String, Set<File>> reverseIndexUsingMerge(final Path path)
throws IOException {
final ConcurrentHashMap<String, Set<File>> map = new ConcurrentHashMap<>();

final BiConsumer<? super String, ? super Set<File>> action = (key,
value) -> map.merge(key, value, (existingValue, newValue) -> {
LOGGER.info("Received key: {}, existing value: {}, new value: {}.",
key, existingValue, newValue);

newValue.addAll(existingValue);

return newValue;
});

commonPool().invokeAll(
find(path, 1,
(p, fileAttributes) -> fileAttributes.isRegularFile())
.map(p -> new ReverseIndex(p, action))
.collect(toList()));

return unmodifiableMap(map);
}

private static class ReverseIndex implements Callable<Void> {
private final Path p;
private final BiConsumer<? super String, ? super Set<File>> action;

private static final Pattern AROUND_WHITESPACE = compile("\\s");

private ReverseIndex(final Path p,
final BiConsumer<? super String, ? super Set<File>> action) {
this.p = p;
this.action = action;
}

@Override
public Void call() throws Exception {
reverseIndex().forEach(action);

return null;
}

private Map<String, Set<File>> reverseIndex() {
/* File stream needs to be closed. */
try (Stream<String> lines = lines(p, UTF_8)) {
return lines.flatMap(AROUND_WHITESPACE::splitAsStream)
.collect(
groupingBy(String::toString,
mapping(word -> p.toFile(), toSet())));
} catch (IOException e) {
LOGGER.error("Something went wrong. Get the hell outta here.",
e);

throw new UncheckedIOException(e);
}
}
}

最佳答案

如果没有值(value),则专注于必须完成的工作。你要做的,是创建一个新的Set缺失条目的值。当然,如果您使用具有原子性保证的操作来创建 Set仅添加到 Set将同时发生,这需要使用并发 Set .您可以使用 ConcurrentHashMap创建事实上的 ConcurrentHashSet (它不存在于那种形式)通过映射到一个固定值,如果你让值信令存在是 Boolean.TRUE,这尤其简单。 :

ConcurrentHashMap<String, Set<File>> map=new ConcurrentHashMap<>();
final BiConsumer<? super String, ? super Set<File>> action =
(key, value) -> map.computeIfAbsent(key, x->ConcurrentHashMap.newKeySet())
.addAll(value);

关于multithreading - Java 8 ConcurrentHashMap 合并与 computeIfAbsent,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27926643/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com