【问题标题】:When is angle bracket required in initializing generic type in Java? [duplicate]在 Java 中初始化泛型类型时什么时候需要尖括号? [复制]
【发布时间】:2021-08-29 21:57:14
【问题描述】:

下面三行全部编译,有什么不同吗?如果不是,那么始终坚持第一个,因为它的代码量最少,这是一种好的 Java 做法吗?

Map<String, String> m = new HashMap();
Map<String, String> k = new HashMap<>();
Map<String, String> l = new HashMap<String, String>(); 

当我提供比较器 lambda 时,我不明白为什么没有 的 PriorityQueue 无法编译:

PriorityQueue<Integer> pq = new PriorityQueue(); // compiled
PriorityQueue<Integer> pq = new PriorityQueue((x, y) -> (y - x)); // failed to compile
PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> (y - x)); // compiled

【问题讨论】:

  • PriorityQueue 似乎没有构造函数只接受Comparator。它确实有一个接受 initialCapacity 和一个 Comparator docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html 的 ctor
  • @MattU it does 从 java 8 开始。
  • 那么,OP 使用的是 8 吗? :D 好电话。我什至没有注意我正在查看的文档版本(不是 Java 开发人员)。
  • @MattU 我知道你在开玩笑,但他们使用的是 lambdas,所以是的,他们肯定至少使用了 java 8 :)
  • 不要使用减号作为比较器。减号可以溢出。由于Integer 具有自然顺序,您可以简单地将Comparator.reverseOrder() 传递给构造函数。或(x, y) -&gt; y.compare(x)

标签: java lambda comparator


【解决方案1】:

这是完全等价的行(见diamond):

PriorityQueue<Integer> pq = new PriorityQueue<>((x, y) -> (y - x));
PriorityQueue<Integer> pq = new PriorityQueue<Integer>>((x, y) -> (y - x));

也是等价的(两者都失败了):

new PriorityQueue((x, y) -> (y - x));
new PriorityQueue<Object>((x, y) -> (y - x));

他们失败是因为你不能减去对象类型

【讨论】:

    【解决方案2】:

    您在 Map 案例中给出的第一种形式使用原始类型,并会导致编译器警告。

    $ cat D.java
    import java.util.Map;
    import java.util.HashMap;
    class D {
        Map<String,String> m = new HashMap();
    }
    
    $ javac D.java
    Note: D.java uses unchecked or unsafe operations.
    Note: Recompile with -Xlint:unchecked for details.
    
    $ javac -Xlint:unchecked D.java
    D.java:4: warning: [unchecked] unchecked conversion
        Map<String,String> m = new HashMap();
                               ^
      required: Map<String,String>
      found:    HashMap
    1 warning
    

    所以,你不想这样做。你可以说它只是在泛型被添加之前Java的遗留物。

    这两种形式是等价的:

    Map<String, String> k = new HashMap<>();
    Map<String, String> l = new HashMap<String, String>(); 
    

    这两行中第一行的&lt;&gt; 语法是为了避免第二行的重复而引入的;这是当今首选的语法。

    &lt;&gt; 运算符从上下文中推断出所需的类型;需要的是一个从字符串到字符串的映射,这就是你得到的。 (这是一个非正式的描述,确切的规则在语言规范中)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多