Tom*_*ann 892 java lambda java-8 java-stream
我想使用Java 8的流和lambdas将对象列表转换为Map.
这就是我在Java 7及以下版本中编写它的方法.
private Map<String, Choice> nameMap(List<Choice> choices) {
final Map<String, Choice> hashMap = new HashMap<>();
for (final Choice choice : choices) {
hashMap.put(choice.getName(), choice);
}
return hashMap;
}
Run Code Online (Sandbox Code Playgroud)
我可以使用Java 8和Guava轻松完成此任务,但我想知道如何在没有Guava的情况下完成此操作.
在番石榴:
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, new Function<Choice, String>() {
@Override
public String apply(final Choice input) {
return input.getName();
}
});
}
Run Code Online (Sandbox Code Playgroud)
还有Java 8 lambda的番石榴.
private Map<String, Choice> nameMap(List<Choice> choices) {
return Maps.uniqueIndex(choices, Choice::getName);
}
Run Code Online (Sandbox Code Playgroud)
zap*_*apl 1345
根据Collectors文档,它很简单:
Map<String, Choice> result =
choices.stream().collect(Collectors.toMap(Choice::getName,
Function.identity()));
Run Code Online (Sandbox Code Playgroud)
Uli*_*ses 291
如果您的密钥不保证对列表中的所有元素都是唯一的,则应将其转换为a Map<String, List<Choice>>而不是aMap<String, Choice>
Map<String, List<Choice>> result =
choices.stream().collect(Collectors.groupingBy(Choice::getName));
Run Code Online (Sandbox Code Playgroud)
Ole*_*Ole 146
使用getName()作为键和选择本身作为映射的值:
Map<String, Choice> result =
choices.stream().collect(Collectors.toMap(Choice::getName, c -> c));
Run Code Online (Sandbox Code Playgroud)
Emr*_*lak 22
如果您不想使用Collectors.toMap(),这是另一个
Map<String, Choice> result =
choices.stream().collect(HashMap<String, Choice>::new,
(m, c) -> m.put(c.getName(), c),
(m, u) -> {});
Run Code Online (Sandbox Code Playgroud)
Sah*_*bra 20
列出的大多数答案都会错过列表中有重复项目的情况.在那种情况下,答案会抛出IllegalStateException.请参阅以下代码以处理列表重复项:
public Map<String, Choice> convertListToMap(List<Choice> choices) {
return choices.stream()
.collect(Collectors.toMap(Choice::getName, choice -> choice,
(oldValue, newValue) -> newValue));
}
Run Code Online (Sandbox Code Playgroud)
Ren*_*war 17
还有一个简单方法
Map<String,Choice> map = new HashMap<>();
choices.forEach(e->map.put(e.getName(),e));
Run Code Online (Sandbox Code Playgroud)
Pio*_*r R 16
例如,如果要将对象字段转换为映射:
示例对象:
class Item{
private String code;
private String name;
public Item(String code, String name) {
this.code = code;
this.name = name;
}
//getters and setters
}
Run Code Online (Sandbox Code Playgroud)
并将操作转换为List To Map:
List<Item> list = new ArrayList<>();
list.add(new Item("code1", "name1"));
list.add(new Item("code2", "name2"));
Map<String,String> map = list.stream()
.collect(Collectors.toMap(Item::getCode, Item::getName));
Run Code Online (Sandbox Code Playgroud)
Joh*_*ean 10
如果您不介意使用第三方库,AOL的cyclops-react lib(披露我是贡献者)具有所有JDK Collection类型的扩展,包括List和Map.
ListX<Choices> choices;
Map<String, Choice> map = choices.toMap(c-> c.getName(),c->c);
Run Code Online (Sandbox Code Playgroud)
我试图这样做,并发现,使用上面的答案,当使用Functions.identity()地图的键,然后我有使用本地方法的问题,this::localMethodName因为键入问题实际工作.
Functions.identity()实际上在这种情况下对输入做了一些事情,所以该方法只能通过返回Object并接受一个param来工作Object
为了解决这个问题,我最终放弃了Functions.identity()并使用了s->s.
所以我的代码,在我的情况下列出目录中的所有目录,并为每个目录使用目录的名称作为地图的键,然后调用具有目录名称的方法并返回项目集合,如下所示:
Map<String, Collection<ItemType>> items = Arrays.stream(itemFilesDir.listFiles(File::isDirectory))
.map(File::getName)
.collect(Collectors.toMap(s->s, this::retrieveBrandItems));
Run Code Online (Sandbox Code Playgroud)
另一种可能性仅出现在评论中:
Map<String, Choice> result =
choices.stream().collect(Collectors.toMap(c -> c.getName(), c -> c)));
Run Code Online (Sandbox Code Playgroud)
如果您想使用子对象的参数作为键,则很有用:
Map<String, Choice> result =
choices.stream().collect(Collectors.toMap(c -> c.getUser().getName(), c -> c)));
Run Code Online (Sandbox Code Playgroud)
我使用这种语法
Map<Integer, List<Choice>> choiceMap =
choices.stream().collect(Collectors.groupingBy(choice -> choice.getName()));
Run Code Online (Sandbox Code Playgroud)
您可以使用IntStream创建索引流,然后将它们转换为Map:
Map<Integer,Item> map =
IntStream.range(0,items.size())
.boxed()
.collect(Collectors.toMap (i -> i, i -> items.get(i)));
Run Code Online (Sandbox Code Playgroud)
可以使用流来做到这一点。为了消除显式使用 的需要Collectors,可以toMap静态导入(按照Effective Java,第三版的建议)。
import static java.util.stream.Collectors.toMap;
private static Map<String, Choice> nameMap(List<Choice> choices) {
return choices.stream().collect(toMap(Choice::getName, it -> it));
}
Run Code Online (Sandbox Code Playgroud)
我将编写如何使用泛型和控件反转将列表转换为映射的方法。只是通用的方法!
也许我们有整数列表或对象列表。因此,问题如下:地图的关键是什么?
创建界面
public interface KeyFinder<K, E> {
K getKey(E e);
}
Run Code Online (Sandbox Code Playgroud)
现在使用控制反转:
static <K, E> Map<K, E> listToMap(List<E> list, KeyFinder<K, E> finder) {
return list.stream().collect(Collectors.toMap(e -> finder.getKey(e) , e -> e));
}
Run Code Online (Sandbox Code Playgroud)
例如,如果我们有book对象,则该类将为地图选择键
public class BookKeyFinder implements KeyFinder<Long, Book> {
@Override
public Long getKey(Book e) {
return e.getPrice()
}
}
Run Code Online (Sandbox Code Playgroud)
Map<String, Set<String>> collect = Arrays.asList(Locale.getAvailableLocales()).stream().collect(Collectors
.toMap(l -> l.getDisplayCountry(), l -> Collections.singleton(l.getDisplayLanguage())));
Run Code Online (Sandbox Code Playgroud)
小智 5
这可以通过两种方式完成。让 person 成为我们将用来演示它的类。
public class Person {
private String name;
private int age;
public String getAge() {
return age;
}
}
Run Code Online (Sandbox Code Playgroud)
让people成为要转换为地图的人员列表
1.在列表上使用简单的 foreach 和 Lambda 表达式
Map<Integer,List<Person>> mapPersons = new HashMap<>();
persons.forEach(p->mapPersons.put(p.getAge(),p));
Run Code Online (Sandbox Code Playgroud)
2.在给定列表上定义的流上使用收集器。
Map<Integer,List<Person>> mapPersons =
persons.stream().collect(Collectors.groupingBy(Person::getAge));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
598848 次 |
| 最近记录: |