If you are open to using a third-party library, Eclipse Collections has a Collector which can convert the List to a Bag. Bag is an unordered Collection which allows duplicates and internally maps items to counts. It also has special APIs for working with the occurrences of items.
List<ObjectIntPair<Object>> top3 =
listOfObjects.stream()
.collect(Collectors2.toBag())
.topOccurrences(3);
The List here will (perhaps surprisingly) have four elements, as object1 and object4 will be considered both valid for third place. The method topOccurrences will leave it to you to decide how to handle the case where there are ties.
This code can also implemented using only Eclipse Collections APIs.
MutableList<String> list = Lists.mutable.with(
"object1",
"object2", "object2",
"object3", "object3", "object3",
"object4");
MutableList<ObjectIntPair<String>> top3 =
list.countBy(each -> each).topOccurrences(3);
The method countBy takes a Function, which in this case is just the element. There is also a Collectors2.countBy(Function).
Note: I am a committer for Eclipse Collections.