1. Java's library is badly designed and not intuitive to search through. Contrast with the .NET library, which is logically arranged, making it easy to search for whatever you may want with Intellisense.
2. Java does not advance at a fast rate, and even when new features are added, they're done in a half-assed way.
For example, when Java added generics, they didn't update the JVM to really support them, so List<int> is really just an old-fashioned, type-unsafe List when compiled. Contrast this with Microsoft, who thought that generics were so important that they warranted real VM-level support and not be a language hack.
Another example is some of the ideas for adding properties to Java, one of which includes adding an arrow operator for accessing properties. C#, on the other hand, has had properties since 1.0, and they work great.
While the Javatards are debating whether or not to add closures and properties, C# has already gotten them, as well as lambdas and language-integrated queries. Try and do this in Java:
var list = new List<int>();
var rand = new Random();
for(int i = 0; i < 100; ++i)
list.Add(rand.Next(100));
var inRange = list.FindAll(x => x > 10 && x < 20);
var inRangeLinq = from x in list where x > 10 && x < 20 select x;
foreach(var x in inRangeLinq)
Console.WriteLine("{0}", x);
3. This is minor, but Java packages must be laid out physically as they are syntactically, so if your package is named "com.somecompany.productx", then you have to put the code in "com/somecompany/productx". There's probably a way around that, but it would probably be looked down upon by Javatards. In .NET, you can specify a namespace without caring where the file is.