简体   繁体   中英

How to sort the list by fields in Java Spring Boot?

I relatively recently started teaching Spring and programming. I try to sort the list by date, but I can't. I can't come to the right decision. I will be very grateful for your help.

Is request:

> GET http://localhost:8080/expenses

How do I get a response like this:

{
 “2021-04-22”: [
      {
          “id”: 2,
          “date”: “2021-04-22”,
          “amount”: 12,
          “currency”: “USD”,
          “product”: “Salmon”
      }
  ],
 “2021-04-27”: [
     {
         “id”: 4,
         “date”: “2021-04-27”,
         “amount”: 4.75,
         “currency”: “EUR”,
         “product”: “Beer”
              },
      {
         “id”: 5,
         “date”: “2021-04-27”,
         “amount”: 25.5,
         “currency”: “UAH”,
         “product”: “Sweets”
             }
      ]
 }

Here is my code:

This is my class of Expense:

public class Expense {

    private int id;
    private static int idInc = 0;
    private double amount;
    private String currency;
    private String product;
    private String date;

    public Expense() {
        this.id = idInc++;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public double getAmount() {
        return amount;
    }

    public void setAmount(double amount) {
        this.amount = amount;
    }

    public String getCurrency() {
        return currency;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }

    public String getProduct() {
        return product;
    }

    public void setProduct(String product) {
        this.product = product;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }
}

This is my controller:

@RestController
    public class ExpenseController {
    
        @Autowired
        private ExpenseService expenseService;
    
        @RequestMapping("/expenses")
        public Map<String, Object> all() {
            return expenseService.getAllExpensesList();
        }
    
        @RequestMapping(method = RequestMethod.POST, value = "/expenses")
        public void addExpense(@RequestBody Expense newExpense) {
            expenseService.addExpense(newExpense);
        }
    }

This is my service:

@Service
    public class ExpenseService {
    
        private Map<String, Object> map = new HashMap<>();
    
        public Map<String, Object> getAllExpensesList(){
            return map;
        }
    
        public void addExpense(Expense expense){
    
            if(!map.containsKey(expense.getDate())) {
                List<Expense> al = new ArrayList<>();
                al.add(expense);
                map.put(expense.getDate(), al);
            }
            else if(map.containsKey(expense.getDate())){
                List<Expense> al = new ArrayList<>();
                al.add(expense);
                map.put(expense.getDate(), al);
            }
        }
    }

How to do it right? How to properly sort the list by date?

Your class needs to implement Comparable interface, and You need to @Override the compare method in your class. That should guide you to the right answer

you should use the Comparable interface and use Date object instead of a string to represent the date.


import java.time.LocalDate;
public class Expense implements Comparable<Expense> {
   // all your fields
   private LocalDate date; // instead of private String date;

   // all getters and setters and constructor

   @Override
   public int compareTo(Expense e) {
      if(this.date.isBefore(e))
        return -1;
      else if(this.date.isAfter(e))
         return 1;
      return 0;
   }

}

while the date is String you can directly deal with compareTo :

if s1 > s2, it returns positive number  
if s1 < s2, it returns negative number  
if s1 == s2, it returns 0  

and for instance, you can use a custom comparator:

Collections.sort(list, (s1, s2) -> s1.getDate().compareTo(s2.getDate()) > 1 ? 1 : s1.getDate().compareTo(s2.getDate()) < 1 ? -1 : 0);

This has nothing to do with Spring. This is a simple grouping by date string, and sort by date operations you are looking at. Sorting can be achieved by using a TreeMap in which the keys are sorted.

I have not compiled this code, so please bear with me if there are any syntax errors.

 Map<String,List<Expense>> resultMap = expenseList.stream().collect(Collectors.groupingBy(Expense::getDate, TreeMap::new, Collectors.toList());

The above code will give you the Map that you are expecting. You'll need to implement Comparable interface for TreeMap to sort the keys for you. Something like,

 @Override
  public int compareTo(Expense o) {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    try {
      return sdf.parse(this.date).compareTo(sdf.parse(o.getDate()));
    } catch (Exception e) {
      System.err.println(e.getMessage()); //Please handle it better!
    }
    return 0;
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM