如何使用Java8流将数组转换为HashMap
我正在编写一个函数,使用Java8流将数组转换为映射 这是我想要的如何使用Java8流将数组转换为HashMap,java,arrays,hashmap,java-8,java-stream,Java,Arrays,Hashmap,Java 8,Java Stream,我正在编写一个函数,使用Java8流将数组转换为映射 这是我想要的 public static <K, V> Map<K, V> toMap(Object... entries) { // Requirements: // entries must be K1, V1, K2, V2, .... ( even length ) if (entries.length % 2 == 1) { throw new IllegalArgum
public static <K, V> Map<K, V> toMap(Object... entries) {
// Requirements:
// entries must be K1, V1, K2, V2, .... ( even length )
if (entries.length % 2 == 1) {
throw new IllegalArgumentException("Invalid entries");
}
// TODO
Arrays.stream(entries).????
}
公共静态映射toMap(对象…条目){
//要求:
//条目必须是K1、V1、K2、V2等(偶数长度)
if(entries.length%2==1){
抛出新的IllegalArgumentException(“无效条目”);
}
//待办事项
数组。流(条目)。????
}
有效用法
Map<String, Integer> map1 = toMap("k1", 1, "k2", 2);
Map<String, String> map2 = toMap("k1", "v1", "k2", "v2", "k3", "v3");
Map<String, Integer> map1 = toMap("k1", 1, "k2", 2, "k3");
map1=toMap(“k1”,1,“k2”,2);
map2=toMap(“k1”、“v1”、“k2”、“v2”、“k3”、“v3”);
无效用法
Map<String, Integer> map1 = toMap("k1", 1, "k2", 2);
Map<String, String> map2 = toMap("k1", "v1", "k2", "v2", "k3", "v3");
Map<String, Integer> map1 = toMap("k1", 1, "k2", 2, "k3");
map1=toMap(“k1”,1,“k2”,2,“k3”);
有什么帮助吗
谢谢 以下是我对JDK 8 stream的想法:
public static <K, V> Map<K, V> toMap(final Object... entries) {
// Requirements:
// entries must be K1, V1, K2, V2, .... ( even length )
if (entries.length % 2 == 1) {
throw new IllegalArgumentException("Invalid entries");
}
final Map<K, V> map = new HashMap<>((int) (entries.length / 2 * 1.25 + 1));
IntStream.range(0, entries.length / 2).forEach(i -> map.put((K) entries[i * 2], (V) entries[i * 2 + 1]));
return map;
// OR:
// return IntStream.range(0, entries.length / 2).boxed().reduce(new HashMap<K, V>(), (m, i) -> {
// m.put((K) entries[i * 2], (V) entries[i * 2 + 1]);
// return m;
// }, (a, b) -> {
// a.putAll(b);
// return b;
// });
}
公共静态映射toMap(最终对象…条目){
//要求:
//条目必须是K1、V1、K2、V2等(偶数长度)
if(entries.length%2==1){
抛出新的IllegalArgumentException(“无效条目”);
}
最终映射=新的HashMap((int)(entries.length/2*1.25+1));
IntStream.range(0,entries.length/2).forEach(i->map.put((K)entries[i*2],(V)entries[i*2+1]);
返回图;
//或:
//返回IntStream.range(0,entries.length/2).boxed().reduce(新的HashMap(),(m,i)->{
//m.put((K)条目的[i*2],(V)条目的[i*2+1]);
//返回m;
//},(a,b)->{
//a.putAll(b);
//返回b;
// });
}
如果您不介意使用第三方库,代码可以简化为:
public static <K, V> Map<K, V> toMap2(final Object... entries) {
// Requirements:
// entries must be K1, V1, K2, V2, .... ( even length )
if (entries.length % 2 == 1) {
throw new IllegalArgumentException("Invalid entries");
}
return Stream.of(entries).split0(2).toMap(e -> (K) e.get(0), e -> (V) e.get(1));
}
公共静态映射toMap2(最终对象…条目){
//要求:
//条目必须是K1、V1、K2、V2等(偶数长度)
if(entries.length%2==1){
抛出新的IllegalArgumentException(“无效条目”);
}
返回流.of(条目).split0(2).toMap(e->(K)e.get(0),e->(V)e.get(1));
}
我认为最有效的方法是通过for循环,如果您不特别追求使用streamapi的话
public static <K, V> Map<K, V> toMap3(final Object... entries) {
// Requirements:
// entries must be K1, V1, K2, V2, .... ( even length )
if (entries.length % 2 == 1) {
throw new IllegalArgumentException("Invalid entries");
}
final Map<K, V> map = new HashMap<>((int) (entries.length / 2 * 1.25 + 1));
for (int i = 0, len = entries.length; i < len; i++) {
map.put((K) entries[i], (V) entries[++i]);
}
return map;
// OR just call the method in AbacusUtil.
// return N.asMap(entries);
}
publicstaticmap-toMap3(最终对象…条目){
//要求:
//条目必须是K1、V1、K2、V2等(偶数长度)
if(entries.length%2==1){
抛出新的IllegalArgumentException(“无效条目”);
}
最终映射=新的HashMap((int)(entries.length/2*1.25+1));
for(int i=0,len=entries.length;i
对于键类型与其值类型不同的地图,可能无法准确获取所需内容。这是因为Java的变量arity声明(对象…条目的部分)只支持一种类型
我想到了一些选择:
您可以动态执行检查,如果值不匹配,则抛出非法参数异常。但是您将丢失编译器类型检查
您可以定义一个对
类,并使用静态导入来获得您想要的:
e、 g:
class Pair<K,V> {
final K k;
final V v;
Pair( K ak, V av) {
k=ak;
v=av;
}
static <A,B> Pair<A,B> p(A a, B b) {
return new Pair(a,b);
}
}
public class JavaTest8 {
<K,V> Map<K,V> toMap( Pair<K,V>... pairs ) {
return Arrays.stream(pairs).collect(Collectors.toMap(p->p.k, p->p.v));
}
public static void main(String[] args) {
// Usage
Map<String,Integer> sti = toMap( p("A",1), p("B",2) );
Map<Integer,Boolean> itb = toMap( p(1,true), p(42,false) );
}
}
类对{
最终K;
最后V V;
配对(K ak,V av){
k=ak;
v=av;
}
静态对p(A,B){
返回新的一对(a,b);
}
}
公共类JavaTest8{
映射到映射(成对…成对){
返回数组.stream(pairs).collect(collector.toMap(p->p.k,p->p.v));
}
公共静态void main(字符串[]args){
//用法
Map sti=toMap(p(“A”,1),p(“B”,2));
图itb=toMap(p(1,真),p(42,假));
}
}
您可以使用地图文字之类的东西。
为了实现这一点,您可以使用工厂方法:
// Creates a map from a list of entries
@SafeVarargs
public static <K, V> Map<K, V> mapOf(Map.Entry<K, V>... entries) {
LinkedHashMap<K, V> map = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : entries) {
map.put(entry.getKey(), entry.getValue());
}
return map;
}
// Creates a map entry
public static <K, V> Map.Entry<K, V> entry(K key, V value) {
return new AbstractMap.SimpleEntry<>(key, value);
}
//从条目列表创建映射
@安全变量
公共静态映射映射(Map.Entry…entries){
LinkedHashMap=新建LinkedHashMap();
对于(Map.Entry:entries){
map.put(entry.getKey(),entry.getValue());
}
返回图;
}
//创建一个映射条目
公共静态映射。条目(K键,V值){
返回新的AbstractMap.SimpleEntry(键,值);
}
最后,您可以执行以下操作:
public static void main(String[] args) {
Map<String, Integer> map = mapOf(entry("a", 1), entry("b", 2), entry("c", 3));
System.out.println(map);
}
publicstaticvoidmain(字符串[]args){
Map Map=mapOf(条目(“a”,1)、条目(“b”,2)、条目(“c”,3));
系统输出打印项次(map);
}
输出:
{a=1,b=2,c=3}
我希望这能为您提供正确的方法。您可以使用
public static <K, V> Map<K, V> toMap(Object... entries) {
if(entries.length % 2 == 1)
throw new IllegalArgumentException("Invalid entries");
return (Map<K, V>)IntStream.range(0, entries.length/2).map(i -> i*2)
.collect(HashMap::new, (m,i)->m.put(entries[i], entries[i+1]), Map::putAll);
}
这将创建一个未指定类型的不可变映射,而不是HashMap
,但有趣的是API
有一种方法Map.Entry(kk,vv)
,可以与
entries映射(Map.Entrypublicstaticmap-toMap(函数toKey,函数toValue,E[]E){
final Map newMap=新HashMap();
阵列
.流(e,0,e.长度-1)
.forEach(s->
{
如果(s[0]!=null | | s[1]!=null)
newMap.put(toKey.apply(s[0]),toValue.apply(s[1]);
}
);
返回newMap;
}
公共静态void main(字符串[]args){
对象[][]对象=新对象[10][2];
对象[0][0]=“Ahmet”;
对象[0][1]=28;
对象[1][0]=“Mehmet”;
对象[1][1]=18;
对象[2][0]=“凯末尔”;
对象[2][1]=55;
Map newMap=toMap((Object::toString),(Object v)->Integer.parseInt(v.toString()),objects);
System.out.println(newMap.get(“Ahmet”)+“”+newMap.get(“Kemal”);
}
最好使用好的旧for
循环:)您可能会在此处找到您要查找的内容:。参考资料谢谢。我仍然更喜欢传递键、值,而不是Map.Entry。谢谢。我仍然更喜欢传递键、值,而不是成对传递。
Map<String, Integer> map1 = Map.of("k1", 1, "k2", 2);
Map<String, String> map2 = Map.of("k1", "v1", "k2", "v2", "k3", "v3");
public static <K,V> Map.Entry<K,V> entry(K k, V v) {
return new AbstractMap.SimpleImmutableEntry<>(k, v);
}
public static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries) {
return Arrays.stream(entries)
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
public static <K,V> Map<K,V> of() {
return new HashMap<>();// or Collections.emptyMap() to create immutable maps
}
static <K,V> Map<K,V> of(K k1, V v1) {
return ofEntries(entry(k1, v1));
}
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2) {
return ofEntries(entry(k1, v1), entry(k2, v2));
}
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3) {
return ofEntries(entry(k1, v1), entry(k2, v2), entry(k3, v3));
}
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
return ofEntries(entry(k1, v1), entry(k2, v2), entry(k3, v3), entry(k4, v4));
}
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
return ofEntries(entry(k1, v1), entry(k2, v2), entry(k3, v3), entry(k4, v4));
}
public static <K, V, E> Map<K, V> toMap(Function<E, K> toKey, Function<E, V> toValue, E[][] e){
final Map<K, V> newMap = new HashMap<>();
Arrays
.stream(e, 0, e.length - 1)
.forEach(s ->
{
if (s[0] != null || s[1] != null)
newMap.put(toKey.apply(s[0]), toValue.apply(s[1]));
}
);
return newMap;
}
public static void main(String[] args) {
Object[][] objects = new Object[10][2];
objects[0][0] ="Ahmet";
objects[0][1] =28;
objects[1][0] ="Mehmet";
objects[1][1] =18;
objects[2][0] ="Kemal";
objects[2][1] =55;
Map<String, Integer> newMap = toMap((Object::toString), (Object v) -> Integer.parseInt(v.toString()), objects);
System.out.println(newMap.get("Ahmet") + " " + newMap.get("Kemal"));
}