如何将List转换为Map?

20 浏览
0 Comments

如何将List转换为Map?

最近我和一个同事探讨了在Java中将List转换为Map的最佳方法,以及这样做是否有特定的好处。我想知道最佳的转换方法,并且非常感谢任何人能够给我指导。以下是一个好的方法吗:\nList results;\nMap resultsMap = new HashMap();\nfor (Object[] o : results) {\n resultsMap.put((Integer) o[0], (String) o[1]);\n}

0
0 Comments

原因:问题的出现可能是因为需要将一个List转换为Map,但是Java标准库中没有提供直接的方法来实现这个转换操作。

解决方法:通过使用Google Collections库中的Maps.uniqueIndex方法可以将List转换为Map。代码如下:

Map mappedRoles = Maps.uniqueIndex(yourList, new Function() {

public String apply(Role from) {

return from.getName(); // or something else

}

});

需要注意的是,Google Collections库已经被Guava库取代,所以建议使用Guava库来进行这个转换操作。Guava库是Google Collections库的一个严格兼容的超集。

然而,在一些情况下使用外部库来完成这个简单的操作可能会过于繁琐。Java标准库中并没有提供像"map"和"reduce"这样的有用方法,但并不完全必要。

需要注意的是,上述代码使用了Guava库。不幸的是,Guava库在Android平台上的性能比较慢,所以在Android项目中不建议使用这个解决方法。

另外,如果列表中的项具有重复的角色名,上述代码可能会抛出异常。

这个解决方法返回的是一个ImmutableMap。如果需要返回一个可变的Map,是否有其他的替代方法呢?

0
0 Comments

如何将List转换为Map?

问题的出现原因是想要将一个List转换为Map。解决方法是通过遍历List中的元素,使用元素的某个属性作为key,在Map中添加相应的键值对。

下面是一个示例代码:

List list;
Map map = new HashMap(list.size());
for (Item i : list) {
    map.put(i.getKey(), i);
}

这里假设每个Item对象都有一个`getKey()`方法,该方法返回一个正确类型的键。

你也可以使用列表中的位置作为key。

下面是对一些问题的解答:

问题:我需要将`getKey()`设置为特定的参数吗?

回答:不需要,`getKey()`是根据你自己的需求来确定的。

问题:在Map中的值是什么?能给出一个示例吗?

回答:值是列表中的项,键是使该项唯一的某个属性。Jim使用的`getKey()`是任意的。

问题:所以基本上我将列表中的元素位置作为键,将其值作为值来填充Map,对吗?

回答:是的,这种做法是可以的。

问题:还有其他的做法吗?

回答:有很多其他的方法,但是对于已知大小的列表,上述示例代码是干净且足够的,不需要为处理每个项而编写回调函数。无论有什么高级的流或者工具函数,这种方法都是最好的选择。

0
0 Comments

如何将List转换为Map?在Java 8中,您可以使用流和Collectors类在一行代码中完成此操作。

以下是一个简短的示例:

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Test{
    public static void main (String [] args){
        List list = IntStream.rangeClosed(1, 4)
                                   .mapToObj(Item::new)
                                   .collect(Collectors.toList()); //[Item [i=1], Item [i=2], Item [i=3], Item [i=4]]
        Map map = 
            list.stream().collect(Collectors.toMap(Item::getKey, item -> item));
        map.forEach((k, v) -> System.out.println(k + " => " + v));
    }
}
class Item {
    private final int i;
    public Item(int i){
        this.i = i;
    }
    public String getKey(){
        return "Key-"+i;
    }
    public String toString() {
        return "Item [i=" + i + "]";
    }
}

输出结果为:

Key-1 => Item [i=1]
Key-2 => Item [i=2]
Key-3 => Item [i=3]
Key-4 => Item [i=4]

上述示例中,我们通过将List转换为流并使用Collectors.toMap方法来将其转换为Map。其中,getKey方法用于作为Map的键,而item本身作为Map的值。

如果您的函数不是双射的,您可以使用二元操作符。例如,假设我们有一个List和一个函数,该函数计算int值的结果对3取模:

List intList = Arrays.asList(1, 2, 3, 4, 5, 6);
Map map = 
    intList.stream().collect(Collectors.toMap(i -> String.valueOf(i % 3), i -> i));

当运行此代码时,您会收到一个错误,即java.lang.IllegalStateException: Duplicate key 1。这是因为1 % 3与4 % 3相同,因此具有相同的键值。在这种情况下,您可以提供一个合并操作符。例如,使用Integer::sum方法引用来计算值的总和:

Map map = 
    intList.stream().collect(Collectors.toMap(i -> String.valueOf(i % 3), 
                                               i -> i, 
                                               Integer::sum));

上述示例输出结果为:

0 => 9 (即3 + 6)
1 => 5 (即1 + 4)
2 => 7 (即2 + 5)

在转换List为Map时,您可以使用Function.identity()代替item -> item,它返回t -> t。这两种方法都可以正常工作,具体取决于个人偏好。

需要注意的是,如果您的类不是POJO,而只是字符串或整数,您不能使用::getKey方法引用。

使用流可能会损失性能,除非您处理的是非常大的数据集。您可以在这里阅读有关性能损失的评论。

值得一提的是,在Android中,流API是在API Level 24中添加的。

希望这个例子对您有所帮助!

0