private void doSortData(List<T> data) {

		if (newSortContext.isUnsorted()) {
			return;
		}

		int size = data.size();
		monitor.setMessage("Sorting " + model.getName() + " (" + size + " rows)" + "...");

		Comparator<T> comparator = newSortContext.getComparator();
		Comparator<T> monitoredComparator = new MonitoredComparator<>(comparator, monitor, size);

		// copy the data. If the sort is cancelled, the data could be corrupted
		List<T> copy = new ArrayList<>(data);
		try {
			Collections.sort(data, monitoredComparator);
		}
		catch (SortCancelledException e) {
			// restore copy as data could be corrupted
			data.clear();
			data.addAll(copy);
		}
		catch (Exception e) {
			// We added this to catch an issue if the sort comparators violate the contract of
			// Comparator.  TimSort will throw an exception in this case.  We have decided to not
			// throw the exception.  This will allow the currently loaded data to be used, albeit
			// unsorted.
			Msg.error(this, "Unable to finish table sorting", e);
			// restore copy as data could be corrupted
			data.clear();
			data.addAll(copy);
		}

		monitor.setMessage("Done sorting");
	}
Work method to sort the data.
Ghidra/Framework/Docking/src/main/java/docking/widgets/table/threaded/TableUpdateJob.java