In the context of the comments and answers given at List.of() or Collections.emptyList() and List.of(...) or Collections.unmodifiableList() I came up with two following rul
First of all, it is important to note that the collection factories return immutable variants. Unfortunately, this does not show in the type system so you have to track that manually / mentally. This already forbids some replacements that might otherwise be worthwile, so it must become 0. in your list of rules. :)
For example, creating a collection of seed elements that are later modified by other code might look like this:
private final Set commonLetters = initialCommonLetters()
private static Set initialCommonLetters() {
Set letters = new HashSet<>();
letters.add("a");
letters.add("e");
return letters;
}
Would be great to simply write commonLetters = Set.of("a", "e"); but this will likely break other code as the returned set is immutable.
The (im)mutability discussion immediately leads to constants. This was a major reason to introduce them! Gone are the days where you need a static initializer block to create that COMMON_LETTERS constant. This would hence be the place where I would look first for use cases.
As you say, there seems to be no reason to start replacing calls to Collections::empty..., Collections::singleton..., or Arrays::asList just for the fun of it. What I would do, though, as soon as I start using the new methods in a class I would replace the old variants as well to have the code rely on fewer concepts, making understanding it easier.
The last argument is also one that could apply to the of() variants in general. While Collections::empty... and Collections::singleton... are somewhat clearer about their intent, I slightly tend towards saying that always using of, no matter how many arguments you have, offsets that advantage by writing code that, as a whole, uses less concepts.
I see no reason to continue using Arrays::asList.