Why Does Spring Use Bubble Sort?
29 Apr 2025You might be surprised to learn that, as of version 6, Spring Framework includes an implementation of Bubble Sort.
Though hidden away in a package-protected method, you will find it here, in MediaTypeUtils
:
static <T> void bubbleSort(List<T> list, BiPredicate<T, T> swap) {
int len = list.size();
for (int i = 0; i < len; i++) {
for (int j = 1; j < len - i; j++) {
T prev = list.get(j - 1);
T cur = list.get(j);
if (swap.test(prev, cur)) {
list.set(j, prev);
list.set(j - 1, cur);
}
}
}
}
Bubble Sort is widely known to be inefficient.
So why is it used in Spring?
Why not rely on more efficient algorithms like Merge Sort, which backs Java’s own Collections.sort
and Arrays.sort
?
To understand the reasoning, we need to look at where and how this method is used.
Sorting Media Types by Specificity
Since this method appears in MediaTypeUtils
, it is no surprise that its usage is related to media types (text/html
, image/png
, application/json
).
Specifically, it is used in the sortBySpecificity
method.
This sorting process is part of content negotiation in Spring MVC, which happens when an HTTP request is resolved to a @Controller
method.
It is closely tied to the Accept
header, which indicates which response media types the client can accept.
Both the values in the Accept
header and the produces
element on @RequestMapping
can be provided in any order.
To match the request to the most appropriate method, Spring MVC determines the most specific acceptable media type that is compatible with the method’s produces
condition.
To do that, it first needs to sort the media types by specificity.
How Specificity is Determined
Given two media types, Spring uses the following rules to determine which is more specific:
- If one has a wildcard type (
*/*
) and the other does not, the non-wildcard is more specific.
Example:text/*
is more specific than*/*
. - If one has a wildcard subtype and the other does not, the non-wildcard is more specific.
Example:text/plain
is more specific thantext/*
. - If both have the same type and subtype, the one with more parameters is more specific.
Example:text/plain;format=flowed
is more specific thantext/plain
. - Otherwise, the media types are considered equally specific.
Why Not Use Collections.sort
?
At first glance, this seems like a problem a Comparator
could solve.
In fact, Spring 5 and earlier used a dedicated Comparator
to sort media types by specificity.
However, that comparator was deprecated in Spring 6. Why?
Because the specificity relation described above forms a partial order, not a total one.
The Javadoc for Comparator
specifies:
A comparison function, which imposes a total ordering on some collection of objects.
But consider text/html
and text/plain
.
Neither is more specific than the other: they are incomparable, which is a valid relationship in a partial order.
A Comparator
has no way to indicate these elements are not comparable; it must yield a less than, equal, or greater than relationship.
Why Bubble Sort Works
Bubble Sort does not require a Comparator
.
Instead, it compares adjacent elements and swaps them if needed, according to a provided condition.
This makes it well-suited to working with partial orders: it only needs to know if one pair is “wrong,” without assuming that every pair can be meaningfully compared.
Additionally, Bubble Sort is a stable sorting algorithm, meaning it preserves the original order of elements that are equal or incomparable.
Preserving original order is crucial when handling Accept
header values.
If you look at the list of default Accept header values used by browsers, they almost always start with text/html
, as browsers obviously mainly consume HTML.
An unstable sort might reorder the list, causing a server to prefer PNGs over HTML; despite the browser clearly expecting the latter.
More efficient algorithms could be adapted for this use case, but Bubble Sort’s simplicity made it a pragmatic choice. That said, Bubble Sort is still inefficient in general, which is why Spring enforces a size limit on the list of media types it is willing to sort this way.
The Broader Lesson
Efficiency is important—but correctness matters even more. Using Bubble Sort in a modern framework may seem counterintuitive, but here it was a deliberate and practical choice.
Choosing the right tool is not about chasing the fastest algorithm; it is about understanding the problem deeply enough to know what truly matters.
Sometimes the “inefficient” algorithm is exactly the right one—when you know your constraints and respect the edge cases.
An earlier version of this post incorrectly described the problem as one of transitivity; thanks to a helpful Reddit comment by JustAGuyFromGermany, it now attributes the issue to the lack of a total order.