1

Code works. It sorts from A to Z. But there are Ç, İ etc. They come after Z which is wrong.

Here is the code

KeyValueDTO.java

public class KeyValueDTO implements Comparable<KeyValueDTO> {
    private String key;
    private String value;

    
    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "KeyValueDTO [key=" + key + ", value=" + value + "]";
    }
    
    @Override
    public int compareTo(KeyValueDTO other) {
        return key.compareTo(other.key);
    }
    
    /*
    public int compare(KeyValueDTO s1, KeyValueDTO s2) {
        Collator collator = Collator.getInstance(new Locale("tr", "TR"));
        return collator.compare(s1, s2);
    }*/
    
}

Controller

@RequestMapping(value = "/getCities", method = RequestMethod.GET)
    @Cacheable("cities")
    public @ResponseBody List<KeyValueDTO> getCities() {
        logger.trace("getCities begins.");
        List<City> cityList = cityService.findAll();
        List<KeyValueDTO> cityKeyDtoList = new ArrayList<KeyValueDTO>();
        

        for (City city : cityList) {
            KeyValueDTO cityKeyDto = new KeyValueDTO();
            cityKeyDto.setKey(city.getName());
            cityKeyDto.setValue(String.valueOf(city.getCode()));
            cityKeyDtoList.add(cityKeyDto);
            
        }
        Collections.sort(cityKeyDtoList);
        // Collections.sort(cityKeyDtoList,Collator.getInstance(new Locale("tr", "TR")));

        logger.trace("CityController: getAllCities ends");
        return cityKeyDtoList;
    }

it works from A to Z, but not Ç İ.. I tried to add Collactor i couldnt use it right way. Could u do some help please?

I wrote this but it doesnt work. It stops running on eclipse.

public @ResponseBody List<KeyValueDTO> getCities() {
        logger.trace("getCities begins.");
        List<City> cityList = cityService.findAll();
        List<KeyValueDTO> cityKeyDtoList = new ArrayList<KeyValueDTO>();
        
        Locale turkish = new Locale("tr", "TR");
        Collator collator = Collator.getInstance(turkish);
        
        for (City city : cityList) {
            KeyValueDTO cityKeyDto = new KeyValueDTO();
            cityKeyDto.setKey(city.getName());
            cityKeyDto.setValue(String.valueOf(city.getCode()));
            cityKeyDtoList.add(cityKeyDto);
            
        }
        //Collections.sort(cityKeyDtoList);
        // Collections.sort(cityKeyDtoList,Collator.getInstance(new Locale("tr", "TR")));
        Collections.sort(cityKeyDtoList, collator);


        logger.trace("CityController: getAllCities ends");
        return cityKeyDtoList;
    }

1 Answers1

4

You have Ç and İ in your data. Let's assume it is Turkish.

import java.text.Collator;
import java.util.Locale;

Locale turkish = new Locale("tr", "TR");
Collator collator = Collator.getInstance(turkish);
Collections.sort(cityKeyDtoList, collator)

enter image description here

Example outcome is given above. Don't mind the class name, non-relevant.


ALTERNATIVE SOLUTION

Changed from Comparable to Comparator.

import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;

public class KeyValueDTO{
    private String key;
    private String value;

    
    public String getKey() {
        return key;
    }

    public void setKey(String key) {
        this.key = key;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

    @Override
    public String toString() {
        return "KeyValueDTO [key=" + key + ", value=" + value + "]";
    }
    
    public Comparator<KeyValueDTO> comparisonOrder() {
        return new CustomComparator();
    }
    private class CustomComparator implements Comparator<KeyValueDTO> {

        @Override
        public int compare(KeyValueDTO o1, KeyValueDTO o2) {
            Collator collator = Collator.getInstance(new Locale("tr", "TR"));
            return collator.compare(o1.getKey(), o2.getKey());
        }
        
    }

}

example main:


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;


public class Solution {
    public static void main(String[] args ) {
        KeyValueDTO city1= new KeyValueDTO();
        city1.setKey("Adana");
        KeyValueDTO city2= new KeyValueDTO();
        city2.setKey("İstanbul");
        KeyValueDTO city3= new KeyValueDTO();
        city3.setKey("Zonguldak");
        KeyValueDTO city4= new KeyValueDTO();
        city4.setKey("Çanakkale");
        
        List<KeyValueDTO> cityKeyDtoList = new ArrayList<KeyValueDTO>();
        cityKeyDtoList.add(city1);
        cityKeyDtoList.add(city2);
        cityKeyDtoList.add(city3);
        cityKeyDtoList.add(city4);
        
        
        Collections.sort(cityKeyDtoList, city1.comparisonOrder());
        System.out.println(cityKeyDtoList.toString());
    }
}


Muhteva
  • 2,729
  • 2
  • 9
  • 21
  • Could you look at my edit please? i updated `the controller` but it didnt work out –  Jul 30 '21 at 06:20
  • What kind of an error do you get? Can you share it? – Muhteva Jul 30 '21 at 06:26
  • Says `Unable to create requested service` also on developer tools when i request, it shows `Failed` in `network-status` The codes in my question were working before i made changes. I dont know maybe i added your code into wrong place? but idk where and how to correct it –  Jul 30 '21 at 06:30
  • i found this https://ofarukkurt.blogspot.com/2016/12/collections-sort-turkish-character.html but couldnt adjust it into my code either –  Jul 30 '21 at 06:33
  • I made some search about your errors, but they don't seem to be related to the code itself. Rather they seem to be related with the database or something. Are you sure that those errors have occurred when you add the code part related to the ```collator```? – Muhteva Jul 30 '21 at 06:37
  • thanks.. But i cant get the same result.. These things seem so confusing for me, and im expected to do this.. i just did sort from A to Z, it worked. but Ç İ and stuff, i am stucked –  Jul 30 '21 at 06:38
  • yes, if u want i can delete and show you what i am getting. I mean it was working, It shows cities from A to Z, then like Çorum, İstanbul İzmir etc. But after I edit `Controller` it stopped working. –  Jul 30 '21 at 06:45
  • For now, comment the sorting section. Just add the ```locale```, do not add the ```collator``` part. If it doesn't give any error, add the ```collator``` part. If also it doesn't give any error, add the ```Collection.sort``` part. Let's try to find which one causes that error. – Muhteva Jul 30 '21 at 06:53
  • I commented all 3 lines, and added this `Collections.sort(cityKeyDtoList);` it works from A to Z. Now as u said, i only commented out `locale` after commenting `Collections.sort(cityKeyDtoList);` it has no problem. now commenting out `collator` too –  Jul 30 '21 at 07:04
  • when i comment out last part `Collections.sort(cityKeyDtoList, collator);` gives `"Internal Server Error",` –  Jul 30 '21 at 07:09
  • Can you try the alternative solution? You should modify your KeyValueDTO class. It should use Comparator rather than Comparable. – Muhteva Jul 30 '21 at 07:27
  • in DTO i added `public int compare(KeyValueDTO s1,KeyValueDTO s2){ Collator collator = Collator.getInstance(new Locale("tr", "TR")); return collator.compare(s1, s2); }` and implemented Comparator instead of Comparable, but same error.. –  Jul 30 '21 at 08:10
  • ```return collator.compare(o1.getKey(), o2.getKey());```, you have to compare the keys. collator doesn't accept an object rather than a string, that's why you get the error. Copy paste the code I gave above for DTO. And call ```Collections.sort(cityKeyDtoList, cityKeyDtoList.get(0).comparisonOrder());``` in your Controller. It must work. – Muhteva Jul 30 '21 at 08:12
  • it wanted me to add comparisonOrder() method which i didnt have exist... Btw i added this in Controller `Comparator compTr = new Comparator(){ @Override public int compare(KeyValueDTO s1, KeyValueDTO s2) { Collator collator = Collator.getInstance(new Locale("tr" ,"TR")); return collator.compare(s1.getKey(), s2.getKey()); } }; Collections.sort(cityKeyDtoList,compTr);` it works now –  Jul 30 '21 at 08:33
  • I'm very happy that the problem is solved. Error was due to the fact that we tried to use collator for DTO objects rather than DTO keys (string). Overriding ```compare``` method should've solved the problem and yes it did. You can override the ```compare``` method in your Controller or in your DTO class. I preferred doing it in the DTO because I believe it's a nice practice, and you can use that ```CustomComparator``` whenever you want in your project. – Muhteva Jul 30 '21 at 08:38
  • 1
    You are awesome, thank you a lot.. I wish we could chat sometime, i can guess you are much younger than me, but i can learn many from you, –  Jul 30 '21 at 09:06
  • is there any chance to chat with you? id like to ask u some questions towards software world, and computer engineering etc –  Jul 30 '21 at 12:11
  • I tried to open a chat room or something like that on Stackoverflow but I can't invite you, I think you must have at least 20 reputation. Do you have Reddit? If you provide your username, I can write to you. – Muhteva Jul 30 '21 at 14:04
  • thanks, thats my profile https://www.reddit.com/user/semih_here semih_here is my username, id like to chat when u get free –  Jul 31 '21 at 15:05
  • can u look at my newly asked question please? https://stackoverflow.com/questions/68612344/how-can-i-show-or-hide-rows-depending-on-a-value-in-selectbox –  Aug 01 '21 at 16:34