当前位置: 首页 > 面试题库 >

Java:如何从列表转换 到地图 无需迭代

纪晨
2023-03-14
问题内容

我有一个对象列表,需要将其转换为映射,键是每个元素的函数,值是每个元素的另一个函数的列表。实际上,这是根据元素的功能对元素进行分组。

例如,假设一个简单的元素类:

class Element {
    int f1() { ... }
    String f2() { ... }
}

以及这些的列表:

[
    { f1=100, f2="Alice" },
    { f1=200, f2="Bob" },
    { f1=100, f2="Charles" },
    { f1=300, f2="Dave" }
]

然后我想要一张地图,如下所示:

{
    {key=100, value=[ "Alice", "Charles" ]},
    {key=200, value=[ "Bob" ]},
    {key=300, value=[ "Dave" ]}
}

任何人都可以提出在Java中 无需进行迭代
的简洁方法吗?LambdaJ的group方法与Guava的组合Maps.transform几乎到达了那里,但group没有生成地图。


问题答案:

番石榴具有Maps.uniqueIndex(可迭代值,功能keyFunction)和Multimaps.index(可html" target="_blank">迭代值,功能keyFunction),但是它们不转换值。有一些 请求添加实用工具方法来满足您的要求,但是现在,您必须使用Multimaps.index()和Multimaps.transformValues()自行滚动它:

static class Person {
    private final Integer age;
    private final String name;

    public Person(Integer age, String name) {
        this.age = age;
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public String getName() {
        return name;
    }
}

private enum GetAgeFunction implements Function<Person, Integer> {
    INSTANCE;

    @Override
    public Integer apply(Person person) {
        return person.getAge();
    }
}

private enum GetNameFunction implements Function<Person, String> {
    INSTANCE;

    @Override
    public String apply(Person person) {
        return person.getName();
    }
}

public void example() {
    List<Person> persons = ImmutableList.of(
            new Person(100, "Alice"),
            new Person(200, "Bob"),
            new Person(100, "Charles"),
            new Person(300, "Dave")
    );

    ListMultimap<Integer, String> ageToNames = getAgeToNamesMultimap(persons);

    System.out.println(ageToNames);

    // prints {100=[Alice, Charles], 200=[Bob], 300=[Dave]}
}

private ListMultimap<Integer, String> getAgeToNamesMultimap(List<Person> persons) {
    ImmutableListMultimap<Integer, Person> ageToPersons = Multimaps.index(persons, GetAgeFunction.INSTANCE);
    ListMultimap<Integer, String> ageToNames = Multimaps.transformValues(ageToPersons, GetNameFunction.INSTANCE);

    // Multimaps.transformValues() returns a *lazily* transformed view of "ageToPersons"
    // If we want to iterate multiple times over it, it's better to create a copy
    return ImmutableListMultimap.copyOf(ageToNames);
}

可重用的实用程序方法可以是:

public static <E, K, V> ImmutableListMultimap<K, V> keyToValuesMultimap(Iterable<E> elements, Function<E, K> keyFunction, Function<E, V> valueFunction) {
    ImmutableListMultimap<K, E> keysToElements = Multimaps.index(elements, keyFunction);
    ListMultimap<K, V> keysToValuesLazy = Multimaps.transformValues(keysToElements, valueFunction);
    return ImmutableListMultimap.copyOf(keysToValuesLazy);
}

我想我们可以通过使用Function<? extends E, K>或某些方法来改进签名中的泛型,但是我没有时间进一步研究…



 类似资料:
  • 问题内容: 我想转换一个从Java中8是这样的: 因为我有一个字符串列表,所以我想创建一个Map,键是列表的字符串,值是Integer(零)。 我的目标是计算字符串列表的元素(在我的代码中稍后)。 我知道以“旧”方式进行转换很容易; 但我想知道是否还有Java 8解决方案。 问题答案: 如前所述,参数必须是函数,因此必须更改为(可以使用任何其他参数名称代替)。 但是请注意,如果中存在重复项,此操作

  • 问题内容: 最近我谈话有什么将要转换的最佳方式是同事,以在Java中,如果有这样做的任何特殊利益。 我想知道最佳转换方法,如果有人可以指导我,我将不胜感激。 这是个好方法吗? 问题答案: 当然,假设每个Item都有一个返回正确类型的键的方法。

  • 我有这样一个代码: 你能帮我完成代码库吗?

  • 问题内容: 我需要转换为。我已经为这个问题苦苦挣扎了一段时间。 很明显如何转换为: 但是我找不到解决最初的问题。有一些易于使用的Java-8方法吗? 问题答案: 我想您很亲密,您需要将这些条目添加到a 并从那里收集。我使用了已经存在的,但是您也可以使用某种。 好吧,如果您不想增加这些实例的额外开销,则可以做些不同:

  • 我有一个java map:

  • 我知道我应该使用函数,但我不知道如何使用,也没有看到它的任何示例。