【问题标题】:Type inference problem: "incompatible types: cannot infer type-variable(s) T,K,U" for map inside stream类型推断问题:“不兼容的类型:无法推断类型变量 T、K、U”用于流内的映射
【发布时间】:2021-10-23 11:26:44
【问题描述】:

我对下面的代码有问题(不要注意它的意思,简化只是为了显示错误):

package net.igorok;

import java.util.*;

public class Main {
    public static void main(String[] args) {

        EntryRecord<Integer, String> data_1 = new EntryRecord(0, "Xiaomi");
        EntryRecord<Integer, String> data_2 = new EntryRecord(1, "Apple");

        List<EntryRecord<Integer, String>> data = new ArrayList<>();
        data.add(data_1);
        data.add(data_2);

        Operation operation = new Operation();
        operation.transform(data);
    }
}

.

package net.igorok;

public class EntryRecord<K,V> {
    private K key;
    private V value;

    public EntryRecord(K key, V value) {
        this.key = key;
        this.value = value;
    }

    public K getKey() {
        return key;
    }
    public V getValue() {
        return value;
    }

    //public void setKey(K key), setValue(V value), equals(), hashcode()...
}

.

package net.igorok;

import java.util.Collection;

public interface OperationContract<V, R> {
    Collection<R> transform(Collection<V> collection);
}

.

package net.igorok;

import java.util.*;
import java.util.stream.Collectors;

public class Operation<V, R> implements OperationContract<V, R> {

    @Override
    public Collection<R> transform(Collection<V> collection) {
        Map<Integer, String> map = (Map<Integer, String>)  collection.stream()
                .collect(Collectors.toMap(EntryRecord::getKey, EntryRecord::getValue));

        // Do not pay attention to return, it is just for example
        return new ArrayList();
    }
}

在这个类中,“EntryRecord::getKey”和“EntryRecord::getValue”用红色标记(“非静态方法不能从静态上下文中引用”,但据我了解,这是一个 IntelliJ IDEA 错误)。

我在尝试编译时收到的消息是: .

/home/punisher/Dropbox/IdeaProjects/ToSOF/src/net/igorok/Operation.java:11:42 java: incompatible types: cannot infer type-variable(s) T,K,U
    (argument mismatch; invalid method reference
      method getKey in class net.igorok.EntryRecord<K,V> cannot be applied to given types
        required: no arguments
        found:    java.lang.Object
        reason: actual and formal argument lists differ in length)

.

我已经阅读了一些类似问题的类似帖子,但我不明白,我需要在代码中更改什么。我明白,这是因为类型推断,但我在泛型和类型推断方面并不强。

您能否告诉我,我可以在代码中进行哪些更改以使其正常工作?为什么?

谢谢!

【问题讨论】:

  • 你为什么投到raw typeArrayList?你根本不需要投射。 Collection 已经有一个可以调用的 stream 方法。
  • 不仅如此,如果有人传入任何其他Collection,即使您的签名声称支持它,您也会引入毫无意义的失败。
  • 谢谢!是的,这是一个关于 ArrayList 的错误。对于整个表达式,它必须强制转换为(Map),但集合没有强制转换为 ArrayList。这是因为我的工作示例没有任何泛型,并且下一次我的代码迭代没有工作。
  • 你好,伊戈尔。显然在您的实现中 V 不是 EntryRecord

标签: java collections java-stream type-inference collectors


【解决方案1】:
public class Operation<V, R> implements OperationContract<V, R> {

    @Override
    public Collection<R> transform(Collection<V> collection) {
        Map<Integer, String> map = (Map<Integer, String>) collection.stream()
           .map(e -> (EntryRecord<Integer, String>)e)
                .collect(Collectors.toMap(EntryRecord::getKey, EntryRecord::getValue));

        // Do not pay attention to return, it is just for example
        return new ArrayList();
    }
}

适用于您的情况。但是,总的来说,这不是一个“好”的代码。

【讨论】:

  • 太棒了!谢谢!我没有足够的声誉将您的答案标记为有用,但它有效!让我问你,它可以在哪里重构以使其在你的愿景中“好”?
  • 我不知道用这段代码完成你的任务。所以这只是我的假设。也许你可以重写泛型来摆脱从 V 到 EntryRecord 的转换。
猜你喜欢
  • 2020-02-18
  • 2018-02-25
  • 2021-05-27
  • 2019-03-20
  • 2014-12-27
  • 2023-03-08
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多