← Назад к вопросам

Как отсортировать данные в порядке убывания

1.8 Middle🔥 131 комментариев
#Другое

Комментарии (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());
    }
}

Лучшие практики

  1. В БД — сортируй при запросе (ORDER BY), не после
  2. Большие данные — используй Pageable с сортировкой
  3. Памяти — не сортируй всё сразу, используй Stream
  4. Индексы — для частой сортировки создавай индексы
  5. Производительность — сравни скорость разных методов
  6. Null значения — помни о сортировке null (обычно в конце)
  7. Компаратор — делай его простым и быстрым
  8. Кэширование — кэшируй результаты сортировки если часто одно и то же
Как отсортировать данные в порядке убывания | PrepBro