Java 将哈希映射拆分为两个较小的映射
我有一个K,V值为的hashmap,我想把它分成两个子映射Java 将哈希映射拆分为两个较小的映射,java,Java,我有一个K,V值为的hashmap,我想把它分成两个子映射 HashMap 一种方法是,我发现我们可以使用树形映射和子映射 TreeMap<Integer, Integer> sorted = new TreeMap<Integer, Integer>(bigMap); SortedMap<Integer, Integer> zeroToFortyNine = sorted.subMap(0, 50); SortedMap<Integer, Integ
HashMap
一种方法是,我发现我们可以使用树形映射和子映射
TreeMap<Integer, Integer> sorted = new TreeMap<Integer, Integer>(bigMap);
SortedMap<Integer, Integer> zeroToFortyNine = sorted.subMap(0, 50);
SortedMap<Integer, Integer> fiftyToNinetyNine = sorted.subMap(50, 100);
TreeMap sorted=新的TreeMap(bigMap);
SortedMap zeroToFortyNine=已排序的.subMap(0,50);
SortedMap Fiftytytonetynine=已排序的.subMap(50100);
但问题是我没有得到jsonObject的subMap,我只想使用HashMap
谢谢您可以循环浏览条目集并填充两个不同的地图:
Map<Long, JSONObject> m = null;
Map<Long, JSONObject> zeroToFortyNine = new HashMap<>();
Map<Long, JSONObject> fiftyToNinetyNine = new HashMap<>();
m.forEach((k, v) -> {
if(k < 50) {
zeroToFortyNine.put(k, v);
} else {
fiftyToNinetyNine.put(k, v);
}
});
m.clear();
Map m=null;
Map zeroToFortyNine=newhashmap();
Map fiftytonetynine=新HashMap();
m、 forEach((k,v)->{
if(k<50){
零氟炔。put(k,v);
}否则{
五羟色胺基九(k,v);
}
});
m、 清除();
您可以使用Java 8流式API:
Map=。。。;
AtomicInteger计数器=新的AtomicInteger(0);
Map collect=Map.entrySet()
.stream()
.collect(收集器(
e->counter.getAndIncrement()
这将地图收集为两个半部分,第一个(
map.get(true)
)包含中间下方的所有元素,第二个(map.get(false)
)半部分包含中间上方的所有元素。从您的问题来看,您似乎不关心拆分的标准,你只想把它一分为二。下面的解决方案将相应地起作用。
只需创建一个计数器并插入前半个hashmap,而计数器(原始hashmap的大小)/2则插入后半个hashmap
HashMap<Integer,JSONObject> hmap;
HashMap<Integer,JSONObject> halfhmap1=new HashMap<>();
HashMap<Integer,JSONObject> halfhmap2=new HashMap<>();
int count=0;
for(Map.Entry<Long, JSONObject> entry : map.entrySet()) {
(count<(hmap.size()/2) ? halfhmap1:halfhmap2).put(entry.getKey(), entry.getValue());
count++;
}
HashMap-hmap;
HashMap halfhmap1=新的HashMap();
HashMap halfhmap2=新的HashMap();
整数计数=0;
对于(Map.Entry:Map.entrySet()){
(count如果无法使用值或键知道拆分的位置,只需计算迭代次数:
Map<Long, String> map = new HashMap<>();
Map<Long, String> sub1 = new HashMap<>();
Map<Long, String> sub2 = new HashMap<>();
int i = 0;
for(Map.Entry<Long, String> e : map.entrySet()){
(i++ % 2 == 0 ? sub1:sub2).put(e.getKey(), e.getValue());
}
Map Map=newhashmap();
Map sub1=新的HashMap();
Map sub2=新的HashMap();
int i=0;
对于(Map.Entry e:Map.entrySet()){
(i++%2==0?sub1:sub2).put(e.getKey(),e.getValue());
}
我使用了一个三元组来增加计数器并选择映射。因此它将平均分割这两个映射上的值
测试:
Map Map=newhashmap();
地图放置(1L,“foo”);
地图放置(2L,“条形”);
地图放置(3L,“代表”);
地图放置(4L,“远”);
Map sub1=新的HashMap();
Map sub2=新的HashMap();
int i=0;
对于(Map.Entry e:Map.entrySet()){
(i++%2==0?sub1:sub2).put(e.getKey(),e.getValue());
}
系统输出打印项次(sub1);
系统输出打印LN(sub2);
{1=foo,3=for}
{2=bar,4=far}
如果需要,可以轻松地将其拆分为3、4或任意数量的地图:
public static void main(String[] args) {
Map<Long, String> map = new HashMap<>();
map.put(1L, "foo");
map.put(2L, "bar");
map.put(3L, "for");
map.put(4L, "far");
Map<Long, String> sub1 = new HashMap<>();
Map<Long, String> sub2 = new HashMap<>();
Map<Long, String> sub3 = new HashMap<>();
split(map, sub1, sub2, sub3);
System.out.println(sub1);
System.out.println(sub2);
System.out.println(sub3);
}
@SafeVarargs
public static <T, U> void split(Map<T,U> map, Map<T,U>... array){
int i = 0;
for(Map.Entry<T, U> e : map.entrySet()){
array[i++% array.length].put(e.getKey(), e.getValue());
}
}
publicstaticvoidmain(字符串[]args){
Map Map=newhashmap();
地图放置(1L,“foo”);
地图放置(2L,“条形”);
地图放置(3L,“代表”);
地图放置(4L,“远”);
Map sub1=新的HashMap();
Map sub2=新的HashMap();
Map sub3=新的HashMap();
拆分(映射,sub1,sub2,sub3);
系统输出打印项次(sub1);
系统输出打印LN(sub2);
系统输出打印项次(sub3);
}
@安全变量
公共静态无效拆分(映射、映射…数组){
int i=0;
对于(Map.Entry e:Map.entrySet()){
数组[i++%array.length].put(e.getKey(),e.getValue());
}
}
{1=foo,4=far}
{2=bar}
{3=for}
您可以使用一些番石榴的功能来划分一个集合
Map<Object, Object> map = new HashMap<>();
List<List<Map.Entry<Object, Object>>> list = Lists.newArrayList(Iterables.partition(map.entrySet(), map.size() / 2 + 1));
Map<Object, Object> map1 = list.get(0).stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map<Object, Object> map2 = list.get(1).stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map Map=newhashmap();
List List=Lists.newArrayList(Iterables.partition(map.entrySet(),map.size()/2+1));
Map map1=list.get(0.stream())
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
Map map2=list.get(1.stream)()
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
您可以通过计算每个分区的项目数(“recordsPerChunk”)将地图拆分为任意数量的部分
以下几点应该行得通
// number of parts for you is 2
int n = 2;
int size = yourMap.size();
int recordsPerChunk =
(size % n == 0) ?
(size / n) :
((size / n) + 1);
// Counter
AtomicInteger ai = new AtomicInteger();
// List with n chunks
Collection chunks =
yourMap
.entrySet()
.stream()
.collect(Collectors.groupingBy(it -> ai.getAndIncrement() / recordsPerChunk))
.values();
拆分HashMap
的标准是什么?它没有顺序,因此将其拆分为“一半”并不容易,因为一半没有定义。使用sorted.entrySet()怎么样
?迭代HashMap并将条目放入其他两个映射。看起来HashMap的键是递增的整数,虽然不能肯定地说抱歉,我的错。删除了它,不必,@Lino覆盖了java 8 soution;)我会使用类似于AtomicBool=new AtomicBoolean(true);map.forEach((k,v)-(bool.getAndSet)的东西(bool.get()^true)?sub1:sub2.put(k,v));
myself@Lino.不,他交替地放入子地图。我正在一个接一个地归档地图。除非键不是从1到map.size
,而是随机值。那么您将不会拆分为“等效”大小map@AxelH谢谢你这么说。我已经编辑了使用递增计数器代替主键的代码。我不会想到使用原子计数器,顺便说一下,你可以使用一个整数,map。size
在你的答案中不能容纳long
@AxelH。你在均匀地分布图,而我只是将前半部分取为map,然后另一半变成另一半:)我同意,但我不确定他是否收到了排序后的映射,因为“我只想用HashMap来做。”。所以对我来说,顺序并不重要。最后两个解决方案都是有效的,一个在流中,一个在迭代器中。完美;)
Map<Object, Object> map = new HashMap<>();
List<List<Map.Entry<Object, Object>>> list = Lists.newArrayList(Iterables.partition(map.entrySet(), map.size() / 2 + 1));
Map<Object, Object> map1 = list.get(0).stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
Map<Object, Object> map2 = list.get(1).stream()
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
// number of parts for you is 2
int n = 2;
int size = yourMap.size();
int recordsPerChunk =
(size % n == 0) ?
(size / n) :
((size / n) + 1);
// Counter
AtomicInteger ai = new AtomicInteger();
// List with n chunks
Collection chunks =
yourMap
.entrySet()
.stream()
.collect(Collectors.groupingBy(it -> ai.getAndIncrement() / recordsPerChunk))
.values();