Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Сортировка данных в порядке убывания (DESC)
Сортировка — одна из основных операций при работе с данными. Рассмотрю различные способы сортировки в порядке убывания в Java и SQL.
1. Сортировка коллекций в Java
Использование Collections.sort():
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 9);
// По возрастанию
Collections.sort(numbers);
System.out.println(numbers); // [1, 2, 5, 8, 9]
// По убыванию
Collections.sort(numbers, Collections.reverseOrder());
System.out.println(numbers); // [9, 8, 5, 2, 1]
2. Сортировка через Stream
List<Integer> numbers = Arrays.asList(5, 2, 8, 1, 9);
// По возрастанию
List<Integer> sorted = numbers.stream()
.sorted()
.collect(Collectors.toList());
System.out.println(sorted); // [1, 2, 5, 8, 9]
// По убыванию
List<Integer> descending = numbers.stream()
.sorted(Collections.reverseOrder())
.collect(Collectors.toList());
System.out.println(descending); // [9, 8, 5, 2, 1]
// Или через comparator
List<Integer> descending2 = numbers.stream()
.sorted((a, b) -> b.compareTo(a))
.collect(Collectors.toList());
3. Сортировка объектов
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() { return name; }
public int getAge() { return age; }
}
List<User> users = Arrays.asList(
new User("John", 30),
new User("Jane", 25),
new User("Bob", 35)
);
// По имени (А-Я)
users.sort(Comparator.comparing(User::getName));
// По имени (Я-А)
users.sort(Comparator.comparing(User::getName).reversed());
// По возрасту (по убыванию)
users.sort(Comparator.comparingInt(User::getAge).reversed());
// Через Stream
List<User> sorted = users.stream()
.sorted(Comparator.comparingInt(User::getAge).reversed())
.collect(Collectors.toList());
4. Множественная сортировка
// Сортировка по нескольким критериям
users.sort(
Comparator.comparing(User::getAge).reversed() // Сначала по возрасту (убывание)
.thenComparing(User::getName) // Затем по имени (возрастание)
);
// Через Stream
List<User> sorted = users.stream()
.sorted(
Comparator.comparingInt(User::getAge).reversed()
.thenComparing(User::getName)
)
.collect(Collectors.toList());
5. Сортировка в SQL (ORDER BY)
-- По возрастанию (ASC - по умолчанию)
SELECT * FROM users ORDER BY age;
SELECT * FROM users ORDER BY age ASC;
-- По убыванию
SELECT * FROM users ORDER BY age DESC;
-- Несколько столбцов
SELECT * FROM users
ORDER BY age DESC, name ASC;
-- По индексу столбца
SELECT * FROM users
ORDER BY 3 DESC; -- По третьему столбцу
-- С функциями
SELECT * FROM users
ORDER BY ABS(age) DESC;
SELECT * FROM users
ORDER BY LENGTH(name) DESC;
6. Spring Data JPA сортировка
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
// Простая сортировка
List<User> findAll(Sort sort);
// С параметрами
List<User> findByActive(boolean active, Sort sort);
}
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> getUsersSortedByAge() {
// По возрастанию
return userRepository.findAll(
Sort.by(Sort.Direction.ASC, "age")
);
}
public List<User> getUsersSortedByAgeDesc() {
// По убыванию
return userRepository.findAll(
Sort.by(Sort.Direction.DESC, "age")
);
}
public List<User> getUsersMultipleSort() {
// Несколько критериев
return userRepository.findAll(
Sort.by(
new Sort.Order(Sort.Direction.DESC, "age"),
new Sort.Order(Sort.Direction.ASC, "name")
)
);
}
}
7. Сортировка с Pageable
@Repository
public interface OrderRepository extends JpaRepository<Order, Long> {
// Возвращает страницу отсортированных результатов
Page<Order> findByUserId(Long userId, Pageable pageable);
}
@RestController
@RequestMapping("/api/orders")
public class OrderController {
@Autowired
private OrderRepository orderRepository;
@GetMapping("/user/{userId}")
public Page<Order> getUserOrders(
@PathVariable Long userId,
@RequestParam(defaultValue = "0") int page,
@RequestParam(defaultValue = "20") int size,
@RequestParam(defaultValue = "createdAt") String sortBy,
@RequestParam(defaultValue = "DESC") Sort.Direction direction) {
Pageable pageable = PageRequest.of(
page,
size,
Sort.by(direction, sortBy)
);
return orderRepository.findByUserId(userId, pageable);
}
}
// Использование API:
// GET /api/orders/user/123?page=0&size=20&sortBy=createdAt&direction=DESC
8. Custom сортировка в Comparator
public class CustomSort {
// Сортировка по кастомной логике
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "Banana", "cherry", "Date");
// Сортировка игнорируя регистр, в обратном порядке
words.sort(
(a, b) -> b.compareToIgnoreCase(a)
);
System.out.println(words); // [Banana, Date, cherry, apple]
}
}
// Сортировка по кастомному объекту
public class ProductComparator implements Comparator<Product> {
@Override
public int compare(Product p1, Product p2) {
// Сначала по цене (убывание), потом по названию (возрастание)
int priceCompare = p2.getPrice().compareTo(p1.getPrice());
if (priceCompare != 0) return priceCompare;
return p1.getName().compareTo(p2.getName());
}
}
// Использование
List<Product> products = new ArrayList<>();
products.sort(new ProductComparator());
9. Сортировка в MongoDB
// Spring Data MongoDB
@Repository
public interface ProductRepository extends MongoRepository<Product, String> {
}
@Service
public class ProductService {
@Autowired
private ProductRepository productRepository;
@Autowired
private MongoTemplate mongoTemplate;
public List<Product> findProductsSorted() {
Query query = new Query();
// По убыванию цены
query.with(Sort.by(Sort.Direction.DESC, "price"));
return mongoTemplate.find(query, Product.class);
}
public List<Product> findWithCustomSort() {
// Сложная сортировка
Query query = new Query();
query.with(Sort.by(
new Sort.Order(Sort.Direction.DESC, "rating"),
new Sort.Order(Sort.Direction.ASC, "name")
));
return mongoTemplate.find(query, Product.class);
}
}
10. Оптимизация сортировки
// Плохо: Сортировка больших данных в памяти
List<User> allUsers = userRepository.findAll(); // Берём все данные
allUsers.sort(Comparator.comparingInt(User::getAge).reversed()); // Сортируем в памяти
List<User> topUsers = allUsers.stream().limit(10).collect(Collectors.toList());
// Хорошо: Сортировка в БД, потом paging
PageRequest pageable = PageRequest.of(
0,
10,
Sort.by(Sort.Direction.DESC, "age")
);
Page<User> topUsers = userRepository.findAll(pageable);
11. Практический пример
@Service
public class ReportService {
@Autowired
private OrderRepository orderRepository;
// Отчёт: топ-10 пользователей по потратам
public List<UserSpendingReport> getTopSpenders(LocalDate startDate, LocalDate endDate) {
return orderRepository.findByCreatedAtBetween(startDate, endDate)
.stream()
.collect(Collectors.groupingBy(
Order::getUserId,
Collectors.reducing(
BigDecimal.ZERO,
Order::getTotalAmount,
BigDecimal::add
)
))
.entrySet().stream()
.map(e -> new UserSpendingReport(e.getKey(), e.getValue()))
.sorted(
Comparator.comparing(UserSpendingReport::getTotal).reversed()
)
.limit(10)
.collect(Collectors.toList());
}
}
Лучшие практики
- В БД — сортируй при запросе (ORDER BY), не после
- Большие данные — используй Pageable с сортировкой
- Памяти — не сортируй всё сразу, используй Stream
- Индексы — для частой сортировки создавай индексы
- Производительность — сравни скорость разных методов
- Null значения — помни о сортировке null (обычно в конце)
- Компаратор — делай его простым и быстрым
- Кэширование — кэшируй результаты сортировки если часто одно и то же