Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java8中将hashmap拆分为分区_Java_Collections_Hashmap_Java 8 - Fatal编程技术网

在Java8中将hashmap拆分为分区

在Java8中将hashmap拆分为分区,java,collections,hashmap,java-8,Java,Collections,Hashmap,Java 8,我有hashmap:Map myMap 我想将其拆分为包含映射的列表: List<Map<String,Set<String>>> listofMaps; 地图列表; ,每个地图最多有100个关键点。 我知道如何以常规的方式来做这件事……(在入口集中使用foreach,每100个项目创建一个新地图)。 有没有办法用Java8Lambda或其他什么东西来实现?(类似于Lists.partitions())?将流拆分为有序的固定大小块(如Lists.parti

我有hashmap:
Map myMap

我想将其拆分为包含
映射的列表

List<Map<String,Set<String>>> listofMaps;
地图列表;
,每个地图最多有100个关键点。 我知道如何以常规的方式来做这件事……(在入口集中使用foreach,每100个项目创建一个新地图)。
有没有办法用Java8Lambda或其他什么东西来实现?(类似于
Lists.partitions()
)?

将流拆分为有序的固定大小块(如
Lists.partition
)是不可能的,因为在并行执行中,每个块都必须等待其左空间块被完全处理

但是,如果您不关心生成的子映射中键的顺序(因为它将由
Map#iterator
的方法返回),则可以滚动自定义收集器

private static <K, V> Collector<Map.Entry<K, V>, ?, List<Map<K, V>>> mapSize(int limit) {
    return Collector.of(ArrayList::new,
            (l, e) -> {
                if (l.isEmpty() || l.get(l.size() - 1).size() == limit) {
                    l.add(new HashMap<>());
                }
                l.get(l.size() - 1).put(e.getKey(), e.getValue());
            },
            (l1, l2) -> {
                if (l1.isEmpty()) {
                    return l2;
                }
                if (l2.isEmpty()) {
                    return l1;
                }
                if (l1.get(l1.size() - 1).size() < limit) {
                    Map<K, V> map = l1.get(l1.size() - 1);
                    ListIterator<Map<K, V>> mapsIte = l2.listIterator(l2.size());
                    while (mapsIte.hasPrevious() && map.size() < limit) {
                        Iterator<Map.Entry<K, V>> ite = mapsIte.previous().entrySet().iterator();
                        while (ite.hasNext() && map.size() < limit) {
                            Map.Entry<K, V> entry = ite.next();
                            map.put(entry.getKey(), entry.getValue());
                            ite.remove();
                        }
                        if (!ite.hasNext()) {
                            mapsIte.remove();
                        }
                    }
                }
                l1.addAll(l2);
                return l1;
            }
    );
}
我还没有对它进行广泛的测试。我还认为你可以修改它,使它更通用

例如,您可以接受任意对象,并使用两个函数为正在处理的每个实例生成一个键和一个值

private static <T, K, V> Collector<T, ?, List<Map<K, V>>> mapSize(Function<T, K> keyFunc, Function<T, V> mapFunc, int limit) {
把它叫做:

.collect(mapSize(Map.Entry::getKey, Map.Entry::getValue, size));

使用my
unorderedBatches()
collector from answer:

收集器批处理收集器=
无序批次(100,
Collectors.toMap(Entry::getKey,Entry::getValue),Collectors.toList();
List listofMaps=myMap.entrySet().stream()
.收集(批次收集器);

并不特别。这不是一种可以用Java 8流轻松表达的操作(甚至根本不是)。如果你指的是Guava的
列表.partition
,这是一种可行的方法,可能与Java 8结合使用,尽管你可能会使用
Iterables.partition
。与我之前的方法相比,它的可重用性更强,做得很好。。再说一遍:-)。
private static <T, K, V> Collector<T, ?, List<Map<K, V>>> mapSize(Function<T, K> keyFunc, Function<T, V> mapFunc, int limit) {
l.get(l.size() - 1).put(keyFunc.apply(e), mapFunc.apply(e));
.collect(mapSize(Map.Entry::getKey, Map.Entry::getValue, size));
Collector<Entry<String, Set<String>>, ?, List<Map<String, Set<String>>>> batchesCollector = 
    unorderedBatches(100, 
        Collectors.toMap(Entry::getKey, Entry::getValue), Collectors.toList());
List<Map<String, Set<String>>> listofMaps = myMap.entrySet().stream()
        .collect(batchesCollector);