0

All three lines below compiled, are there any differences? If not, is it a good Java practice to always stick to the first one as it has the least amount of code?

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

And I don't understand why PriorityQueue without <> doesn't compile when I supplied the comparator lambda:

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
braebdeb
  • 219
  • 2
  • 11
user1701840
  • 1,062
  • 3
  • 19
  • 27
  • `PriorityQueue` doesn't seem to have a constructor accepting only a `Comparator`. It does have a ctor accepting `initialCapacity` and a `Comparator` https://docs.oracle.com/javase/7/docs/api/java/util/PriorityQueue.html – Matt U Jun 13 '21 at 21:25
  • 2
    @MattU [it does](https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/PriorityQueue.html#%3Cinit%3E(java.util.Comparator)) since java 8. – Federico klez Culloca Jun 13 '21 at 21:29
  • Well, is OP using 8? :D Good call though. I didn't even pay attention to the version of the docs I was looking at (not a Java dev). – Matt U Jun 13 '21 at 21:33
  • @MattU I know you're joking, but they're using lambdas, so yes, they're definitely using at least java 8 :) – Federico klez Culloca Jun 13 '21 at 21:38
  • No. I was making a guess because I'm not a Java developer. – Matt U Jun 13 '21 at 21:41
  • 2
    Don’t use minus as comparator. Minus can overflow. Since `Integer` has a natural order, you can simply pass `Comparator.reverseOrder()` to the constructor. Or `(x, y) -> y.compare(x)` – Holger Jun 14 '21 at 10:16

2 Answers2

0

It is totally equivalent rows (see diamond):

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

It is equivalent too (failed both):

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

They failed because of you cannot subtract Object type

User9123
  • 1,643
  • 1
  • 8
  • 21
0

The first form you give in the Map case uses raw types, and will result in compiler warnings.

$ 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

So, you don't want to do that. That you can say it at all is just a leftover from Java before generics were added.

These two forms are equivalent:

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

The <> syntax in the first of those two lines was introduced to avoid the repetition in the second; that is preferred syntax these days.

The <> operator infers the required types from context; what is needed is a Map from String to String, so that's what you get. (That's an informal description, the exact rules are in the language specification).

iggy
  • 1,328
  • 4
  • 3