Why does adding "|" to Set in Java flip the elements order? - java

I have two Lists and trying to form a String with element from each List, and in between when I do " ", the sorted order is maintained. But once I put "|" in the middle, which I would want to, the order of the elements in the Set gets switched around.
How can I add "|" and still maintain the sorted order in the Set students?
Here is the code:
Set<String> students = new HashSet<>();
Set<String> fn = new HashSet<>();
Set<String> nums = new HashSet<>();
List<String> firstNames = new ArrayList<>(fn);
Collections.sort(firstNames);
List<String> favNumbers = new ArrayList<>(nums);
Collections.sort(favNumbers);
for(int i=0; i<firstNames.size(); i++) {
students.add(firstNames.get(i) + "|" + favNumbers.get(i));
}
System.out.println(students);
With ... + " " + ..., the order is [Joshua 4, Lyon 7], but if "|" is added in place of " ", the order becomes [Lyon|7, Joshua|4] when I want and should be[Joshua|4, Lyon|7].

A HashSet does not provide any ordering guarantees about its contents, using whatever ordering the underlying HashMap generates, which is in turn based on the hashCode() of the elements.
When you change the contents of a string, you get a different hash code--simple as that. The order in a HashMap is undefined and could change if you inserted additional elements triggering a rehash.
If you want a set with a guaranteed order, you can use a SortedSet implementation (such as TreeSet), but you'd need to write a proper class and implement suitable Comparators. Alternately, you could use LinkedHashSet, which maintains elements in insertion order at the expense of additional overhead.

You should be using object oriented design, as Java is an object oriented language. Instead of trying to represent the various features of a student as independent collection, create a Student POJO which contains these features. Then, create custom comparators to sort by either name or favorite number.
public class Student {
private String firstName;
private String lastName;
private int favNumber;
// getters and setters
public static Comparator<Student> NameComparator
= new Comparator<Student>() {
public int compare(Student s1, Student s2) {
String f1 = s1.getFirstName();
String f2 = s2.getFirstName();
String l1 = s1.getLastName();
String l2 = s2.getLastName();
if (l1.equalsIgnoreCase(l2) {
return f1.toUpperCase().compareTo(f2);
}
else {
return l1.toUpperCase().compareTo(l2);
}
}
};
public static Comparator<Student> FavComparator
= new Comparator<Student>() {
public int compare(Student s1, Student s2) {
return s1.getFavNumber() < s2.getFavNumber();
}
};
}
Now if you have a list of students, List<Student> list, you can sort via:
Collections.sort(list, Student.NameComparator);
Or, to sort by favorite numbers, use:
Collections.sort(list, Student.FavComparator);

From the documentation for HashSet:
It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.
So you cannot rely on HashSet to preserve any kind of order.
It looks to me like you just need to preserve the order of insertion, in which case you're better off not using a Set and rather a List, e.g.,
List<String> students = new ArrayList<>();

Related

How to apply comparator to get the TOP 5 cities from a List sorted by population?

I have a class City
public final class City {
private final String name;
private final String state;
private final int population;
public City(String name, String state, int population) {
this.name = name;
this.state = state;
this.population = population;
}
public String getName() {
return name;
}
public String getState() {
return state;
}
public int getPopulation() {
return population;
}
#Override
public String toString() {
return "City [name=" + name + ", state=" + state + ", population=" + population + "]";
}
}
And a class that implements Observable (not needed for this). This observable class holds an arraylist List<City> cityList that has the data for all the cities that have been reported.
My class TopFiveCities is supposed to:
"implement a getter method getTopFive() returning a list with the five
top cities (in terms of population) received. The list is sorted from
higher to lower numbers. The returned list must be a copy of the list
kept by the observer"
Aside from just getting the top 5 list, I also need to know how to make a copy of that list from the observer.
This is what I have:
public class TopFiveCities
implements Observer {
// THIS ALSO DOESN'T WORK UNLESS THE LIST IS STATIC
// SO HOW CAN I MAKE A COPY OF THE LIST FROM OBSERVER?
private List<City> list = new ArrayList<>(CensusOffice.cityList);
public List<City> getTopFive() {
Collections.sort(list, new Comparator<City>() {
#Override
public int compare(City o1, City o2) {
return Integer.compare(o1.getPopulation(), o2.getPopulation());
}
});
return list;
}
public void update(Observable observable) {
if (!(observable instanceof Observable)) {
throw new IllegalArgumentException();
}
}
}
With this, when one of the sample outputs should be:
City [name=Chicago, state=IL, population=2746388]
I just receive a list of all the cities, sorted by population from LOWEST to HIGHEST. What I'm doing wrong?
You can just use a Stream, use a Comparator to sort the stream, limit the number of element and convert the elements to a new list:
List<City> top5citiesByPopulation = cities.stream()
.sorted(Comparator.comparing(City::getPopulation).reversed())
.limit(5)
.collect(Collectors.toList());
int order = requestedOrder.equals("asc") ? 1 : -1;
Collections.sort(list, new Comparator<CustomObj>() {
public int compare(CustomObj first, CustomObj scnd) {
return first.getComparableParam().compareTo(scnd.getComparableParam()) * order;
}
});
I just copied and passed this code block from recommended stackover page in the comment. Of you want ascending order simply change it. In your code order will be -1.
Simply you need to multiply by -1.
return Integer.compare(o1.getPopulation(), o2.getPopulation()) * -1;
After this you can sublist it.
You keep the list as global variable it can be reached from update method but it does not change if class is singleton except for update method. Your update method can change it by notifying
In update method you can simply clear and add new list by list.addAll
Since this is a schoolwork assignment, I’ll describe the pieces but let you assemble them into final code.
I have a class "City"
You could more briefly define that class as a record.
City ( String name, String state, int population ) {}
holds an array list "List cityList"
List < City > cities = new ArrayList<>();
getting the top 5 list
Sort the list by using a reverse comparator. You can make a comparator for sorting by using a method reference for the accessor “getter” method. But be aware that records do not use the word “get” by default as their accessor, they use simply the name of the property.
cities.sort( Comparator.comparing( City :: population ).reversed() ) ;
For an unmodifiable list, call List.of or List.copyOf.
List#subset gives you a list with some of the elements of the original. But beware: the resulting list is based on a view of the original list. The subset is not separate and independent. To get a separate list, pass to List.copyOf or pass to the constructor of another List implementation.
List< City > topFivePop = List.copyOf( subset ) ;
This problem doesn't require sorting the whole given list, which will have a time complexity of O(n log n).
Basically, the task is somewhat similar to finding the maximum element in the list that can be done in O(n) time with a single pass through the given list.
The most suitable approach for this problem is a partial sorting, and the best performance that could be achieved is the middle-ground between O(n) and O(n log n).
In order to find 5 maximum elements in a list, we can maintain a collection that will store in sorted order up to 5 previously encountered elements with maximum values.
Elements that are lover than the smallest element in the collection will be discarded automatically if the collection is already of size 5. Only new elements with a value higher than the smallest element's value will trigger reordering of this tiny collection. I.e. the data will be sorted partially instead of sorting the whole data set.
In the implementation below for as collection that will store 5 max elements, I've chosen a PriorityQueue.
According to the documentation it's methods have the following time complexity.
this implementation provides O(log(n)) time for the enqueuing and dequeuing methods (offer, poll, remove() and add); linear time for the remove(Object) and contains(Object) methods; and constant time for the retrieval methods (peek, element, and size).
I.e. adding of a new element and removing the first element both will perform in logarithmic time, and accessing the smallest value in the queue with the method element() with done in O(1) time (almost immediately).
The PriorityQueue is encapsulated inside a generic class, which constructor expects as parameters a Comparator<T> and a desired maximum size of the queue (i.e. a number of max elements that needs to be found).
The queue itself doesn't exposed to the outside classes. Method addItem() processing the given element and getFirstN returns a sorted immutable list.
Comparator in the code below is implemented using the static method comparingInt(). You could also implement Comparator in a "classical way" (pre-Java 8) by providing the behavior for it's abstract method compare() either by using a lambda expression or within an anonymous inner class.
public class FirstN<T> {
private final Queue<T> queue;
private final Comparator<T> comparator;
private final int capacity;
public FirstN(Comparator<T> comparator, int capacity) {
this.queue = new PriorityQueue<>(comparator);
this.comparator = comparator;
this.capacity = capacity;
}
public boolean addItem(T item) {
if (capacity == queue.size() && comparator.compare(item, queue.element()) <= 0) {
return false; // queue is full and the given item is smaller than the lowerest element in the queue
}
if (capacity == queue.size() && comparator.compare(item, queue.element()) > 0) {
queue.remove(); // removing the first element if it's smaller than the given item
}
return queue.add(item); // adding the given item
}
public List<T> getFirstN() {
List<T> result = new ArrayList<>(queue); // creating a list based on a queue
result.sort(comparator);
return List.copyOf(result); // making a copy of the list (returned list is immutable)
}
}
main()
public static void main(String[] args) {
List<City> cities = List.of(
new City("Austin", "Texas", 1028225),
new City("Los Angeles", "California", 3985516),
new City("San Diego", "California", 1429653),
new City("Houston", "Texas", 2325353),
new City("Phoenix", "Arizona", 1759943),
new City("New York City", "New York", 8177025),
new City("San Antonio", "Texas", 1598964),
new City("Philadelphia", "Pennsylvania", 1585480),
new City("San Diego", "California", 1429653),
new City("Chicago", "Illinois", 2671635),
new City("Dallas", "Texas", 1348886));
FirstN<City> top5Cities =
new FirstN<>(Comparator.comparingInt(City::getPopulation), 5);
for (City next: cities) {
top5Cities.addItem(next);
}
List<City> result = top5Cities.getFirstN(); // contains 5 biggest US cities
result.forEach(System.out::println); // printing the result
}
Output (order from lowest to highest)
City [name=Phoenix, state=Arizona, population=1759943]
City [name=Houston, state=Texas, population=2325353]
City [name=Chicago, state=Illinois, population=2671635]
City [name=Los Angeles, state=California, population=3985516]
City [name=New York City, state=New York, population=8177025]

how to implement Custom Auto suggestion in java like google

how to implement Java Based Auto suggestion. suppose I have different types of data like firstName, rollNumber, address.
My first requirement is like if user enter first character on text box, then result should be sorted on natural order based on firstName and 10 results should be display.
after space if use enter second character and if it is numbere then RollNumber else lastName should be sorted on natural order as ascending.
or if user type third character then Address should be display on ascending order. there should be no database, you don't have to implement Solr or other api. how to implement on pure Java.
here I did not implement the text-box,but I Just took an example to demonstrate
import java.util.*;
import java.lang.*;
import java.io.*;
// A class to represent a student.
class Student {
int rollno;
String name;
String address;
// Constructor
public Student(int rollno, String name, String address) {
this.rollno = rollno;
this.name = name;
this.address = address;
}
// Used to print student details in main()
public String toString(){
return this.rollno + " " + this.name +
" " + this.address;
}
}
class Sortbyroll implements Comparator<Student> {
// Used for sorting in ascending order of rollno
public int compare(Student a, Student b) {
return a.rollno - b.rollno;
}
}
class Sortbyname implements Comparator<Student> {
// Used for sorting in ascending order of name
public int compare(Student a, Student b) {
return a.name.compareTo(b.name);
}
}
// Driver class
class Main {
public static void main (String[] args) {
ArrayList<Student> ar = new ArrayList<Student>();
//here I have thousand student are inserted into
//simple collection.
ar.add(new Student(111, "bbbb", "london"));
ar.add(new Student(131, "aaaa", "nyc"));
ar.add(new Student(121, "cccc", "jaipur"));
System.out.println("Unsorted");
for (int i=0; i<ar.size(); i++) {
System.out.println(ar.get(i));
}
//collection sorted by rollno
Collections.sort(ar, new Sortbyroll());
System.out.println("\nSorted by rollno");
for (int i=0; i<ar.size(); i++) {
System.out.println(ar.get(i));
}
//sort by Name
Collections.sort(ar, new Sortbyname());
System.out.println("\nSorted by name");
for (int i=0; i<ar.size(); i++) {
System.out.println(ar.get(i));
}
}
}
First of all your question is incomplete and misleading. It does not describes the requirement properly. But overall what I assume
You want Google like (?) suggester in your text box
It does not tell any specific things. What about your front end ? How about your data ?
Any way I think you just wanted to have a console like application where you will give partial String as input and your method will guess the Rest of String as an assumption from your dummy data. Am I right ?
If that is the thing you were looking for then I just sketched a demo code below
static List<String> query(String queryStr, List<Student> list) {
List<String> suggestion = new ArrayList<>();
list.forEach(std -> {
if (isMatched(queryStr, String.valueOf(std.getRoll()))) {
suggestion.add(String.valueOf(std.getRoll()));
}
if (isMatched(queryStr, std.getName())) {
suggestion.add(std.getName());
}
if (isMatched(queryStr, std.getAddress())) {
suggestion.add(std.getAddress());
}
});
return suggestion;
}
private static boolean isMatched(String query, String text) {
return text.toLowerCase().contains(query.toLowerCase());
}
And what does this code do ? It actually takes the Partial String that the user input so far and your List<Student> as parameters. Then it iterates over the list and matches for all field for partial match. If any field matches the query it add that value in the suggestion list. In the main you can do like this :
public static void main(String[] args) {
List<Student> list = new ArrayList<>();
list.add(new Student(101, "Abc ghi", "USA"));
list.add(new Student(102, "DEF", "UST"));
list.add(new Student(103, "Ghi ab", "DSjkD"));
list.add(new Student(104, "jKL ut", "USN"));
list.add(new Student(105, "MNP", "TSA101"));
list.add(new Student(106, "UTC ABC", "ESA"));
List<String> sugg = query("01", list);
sugg.forEach(System.out::println);
}
and you will find the console printed like :
101
TSA101
Does it make sense ? it might not be your whole confusing requirements. But I think you got the idea. You can exploit this to address your own requirements. You could further imply your sorting logic or any kind of filters to it. It should not be that tough thing.
But you should be concerned that with large number of collection or complex associated objects this would not suffice. Real world application does not work this straight forward. You might need lot of other things to consider like memory, i/o and execution time.
Good Luck!
Do refer https://github.com/nikcomestotalk/autosuggest/
This implementation is in java based on Patricia trie and Edit distance algorithm.
Some salient features of this application is
Auto correction of keywords
Bucket support for sorting and personalization support.
Filtering support.
Limit support.
Build in http server.
Blazing fast search.
And you all are welcome for feedback
Solr/Lucene/Elastic will not give freedom to choose algorithm and personalization support.
You can use a Trie data structure for autosuggestion implementation and the time complexity would be O(word_length) for insert and search.
Apache commons provides implementation "org.apache.commons.collections4.Trie"
example:
Trie<String, String> trie = new PatriciaTrie<>();
trie.put("abcd", "abcd");
trie.put("abc", "abc");
trie.put("abef", "abef");
SortedMap<String, String> map = trie.prefixMap("ab");
map.forEach((k, v) -> {
System.out.println(k + " " + v);
});

Remove duplicates from a list in an Arraylist in java

I checked many examples but i could not applied for my variables.
I have a ArratyList Of lists of Strings.
ArrayList<List<String>> bulkUploadList = new ArrayList<List<String>>();
and it's look like this:
[id, title, tags, descriptions]
[4291483113.0000000000000, Camden, camdentown;london, NoValue]
[4292220054.0000000000000, IMG_2720, NoValue, NoValue]
[4292223824.0000000000000, IMG_2917, london;camdentown, NoValue]
[4292224728.0000000000000, IMG_2945, London;CamdenTown, NoValue]
I want to remove those rows which have the same titles and the same tags.
I do not know how work with HashSet since I have a ArrayList of List of Strings.
Not best solution, but you can start with this:
ArrayList<List<String>> bulkUploadList = new ArrayList<List<String>>();
ArrayList<List<String>> result = new ArrayList<List<String>>();
HashSet<String> hashSet = new HashSet<>();
for(List<String> item : bulkUploadList) {
String title = item.get(1);
String tags = item.get(2);
String uniqueString = (title + "#" + tags).trim().toUpperCase();
if(!hashSet.contains(uniqueString)) {
result.add(item);
hashSet.add(uniqueString);
} else {
System.out.println("Filtered element " + uniqueString);
}
}
As suggested in one of the comments, you should create a class for the data, make that class implement equals(), and then use HashSet to remove dups. Like this.
class Foo {
String id;
String title;
String tags;
String description;
public boolean equals(Foo this, Foo other) {
return this.id.equals(other.id)
&& this.title.equals(other.title)
&& etc.
}
then you can remove dups with
Set<Foo> set = new LinkedHashSet<Foo>(list);
as Sets do not allow duplication, and the equals() method is used to check.
You should use a linkedHashSet here because you want to preserve the order (according to a comment you made on elsewhere).
You should also implement a hashcode() method consistent with equals().

Associate multiple values with the single key and also maintain the order of values

I have a class which contain the following members
private String patientName;
private String patientPhoneNumber;
now I have multiple names attached with the phone No. for example
1234567, AAA
1234567, BBB
8765432, CCC
8765432, GGG
Now I want to store them in a Map but the phone No. should be the key having multiple values, for 1234567 i should have value AAA and BBB, please advise how can I store the multiple values with the single key in map here my key is Phone No. and then please let me know if I want to print in console then ow would I iterate over the Map
Also please not that I want to maintain the order also let say first I get the value AAA and then BBB so i should maintain these order also, since I get this is just a example but in my scenario I will be getting this value from backend so to maintain the order is also necessary please advise.
You may try something like this:
HashMap<String,LinkedList<String>> map
private Map<String,List<String>> patients;
public void setPatientNumber(String number, String patient){
List<String> list = patients.get(number);
if(list == null){
list = new ArrayList<String>();
patients.put(number,list);
}
list.add(patient);
}
new Map<String, TreeSet<String>>()
Will allow you to store the values in a TreeSet (sorted...).
To print them:
for(Map.Entry entry : phoneBook.entries()){
System.out.println(entry.key() + ":");
TreeSet names = entry.value();
for(String name : names){
System.out.println("\t" + name);
}
}
You can add, like this, if you want case insensitive ordering:
TreeSet<String> nameSet = new TreeSet<String>(String.CASE_INSENSITIVE_ORDER);
phoneBook.add(number, nameSet);
Use a LinkedHashMap and an ArrayList for each values :
LinkedHashMap<String,ArrayList<String>> phoneNumbers = new LinkedHashMap<String,ArrayList<String>>();
// register new phone number
phoneNumbers.put("1234567", new ArrayList<String>());
// add names to the phone number
phoneNumbers.get("1234567").add("AAA");
phoneNumbers.get("1234567").add("BBB");
Both collections preserve the insertion ordering.
** Edit **
Here, this is roughly what you'd need (this was done on the spot without much testing, but you should get the idea). Since your ordering may vary, I thought limiting duplicates and providing a comparator for ordering should be preferable (as suggested by other answers) :
public class LinkedMultiMap<K,V> {
private Comparator<V> comparator;
private LinkedHashMap<K,Set<V>> entries;
public LinkedMultiMap() {
this(null);
}
public LinkedMultiMap(Comparator<V> comparator) {
this.comparator = comparator;
this.entries = new LinkedHashMap<K, Set<V>>();
}
public boolean add(K key, V value) {
if (!entries.containsKey(key)) {
entries.put(key, new TreeSet<V>(comparator));
}
return entries.get(key).add(value);
}
public Collection<V> get(K key) {
return entries.get(key);
}
public boolean remove(K key, V value) {
boolean removed = false;
if (entries.containsKey(key)) {
removed = entries.get(key).remove(value);
if (entries.get(key).isEmpty()) {
entries.remove(key);
}
}
return removed;
}
public Collection<V> removeAll(K key) {
return entries.remove(key);
}
public Iterator<K> keyIterator() {
return entries.keySet().iterator();
}
}
Associate multiple values with the single key
That is a Multimap:
A collection similar to a Map, but which may associate multiple values with a single key.
LinkedHashMultimap from Google Collections seems to fit the bill:
Implementation of Multimap that does not allow duplicate key-value
entries and that returns collections whose iterators follow the
ordering in which the data was added to the multimap.
If you don't want to add the dependency, you can use a collection as value type:
Map<String /*number*/, List<String> /*names*/> numbers;
Note that the former only allows retrieval in order of insertion, if you want to be able to change it you will have to use the latter hand-rolled solution
Use a Map to store your data. The keys should be String objects and the values should be List objects. Using a List as the map entry value allows to associate multiple values with a single key. A List will also maintain the order of adding elements.
public static void main(String[] args) {
Map<Integer,List<String>> map = new HashMap<Integer,List<String>>();
//insert values into list one
List<String> list1 = new ArrayList<String>();
list1.add("AAA");
list1.add("BBB");
//insert values into list one
List<String> list2 = new ArrayList<String>();
list2.add("CCC");
list2.add("GGG");
//insert values to keys
//single key multiple values
map.put(1234567, list1);
map.put(8765432, list2);
//iterating and displaying the values
for(Map.Entry<Integer,List<String>> entry: map.entrySet() ) {
Integer key = entry.getKey();
List<String> values = entry.getValue();
System.out.println("Value of " +key+ " is " +values);
//System.out.println("Value of " +key+ " is " +values.get(0));
//System.out.println("Value of " +key+ " is " +values.get(1));
}
}

How can I sort a List alphabetically?

I have a List<String> object that contains country names. How can I sort this list alphabetically?
Assuming that those are Strings, use the convenient static method sort:
Collections.sort(listOfCountryNames)
Solution with Collections.sort
If you are forced to use that List, or if your program has a structure like
Create List
Add some country names
sort them once
never change that list again
then Thilos answer will be the best way to do it. If you combine it with the advice from Tom Hawtin - tackline, you get:
java.util.Collections.sort(listOfCountryNames, Collator.getInstance());
Solution with a TreeSet
If you are free to decide, and if your application might get more complex, then you might change your code to use a TreeSet instead. This kind of collection sorts your entries just when they are inserted. No need to call sort().
Collection<String> countryNames =
new TreeSet<String>(Collator.getInstance());
countryNames.add("UK");
countryNames.add("Germany");
countryNames.add("Australia");
// Tada... sorted.
Side note on why I prefer the TreeSet
This has some subtle, but important advantages:
It's simply shorter. Only one line shorter, though.
Never worry about is this list really sorted right now becaude a TreeSet is always sorted, no matter what you do.
You cannot have duplicate entries. Depending on your situation this may be a pro or a con. If you need duplicates, stick to your List.
An experienced programmer looks at TreeSet<String> countyNames and instantly knows: this is a sorted collection of Strings without duplicates, and I can be sure that this is true at every moment. So much information in a short declaration.
Real performance win in some cases. If you use a List, and insert values very often, and the list may be read between those insertions, then you have to sort the list after every insertion. The set does the same, but does it much faster.
Using the right collection for the right task is a key to write short and bug free code. It's not as demonstrative in this case, because you just save one line. But I've stopped counting how often I see someone using a List when they want to ensure there are no duplictes, and then build that functionality themselves. Or even worse, using two Lists when you really need a Map.
Don't get me wrong: Using Collections.sort is not an error or a flaw. But there are many cases when the TreeSet is much cleaner.
You can create a new sorted copy using Java 8 Stream or Guava:
// Java 8 version
List<String> sortedNames = names.stream().sorted().collect(Collectors.toList());
// Guava version
List<String> sortedNames = Ordering.natural().sortedCopy(names);
Another option is to sort in-place via Collections API:
Collections.sort(names);
Better late than never! Here is how we can do it(for learning purpose only)-
import java.util.List;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
class SoftDrink {
String name;
String color;
int volume;
SoftDrink (String name, String color, int volume) {
this.name = name;
this.color = color;
this.volume = volume;
}
}
public class ListItemComparision {
public static void main (String...arg) {
List<SoftDrink> softDrinkList = new ArrayList<SoftDrink>() ;
softDrinkList .add(new SoftDrink("Faygo", "ColorOne", 4));
softDrinkList .add(new SoftDrink("Fanta", "ColorTwo", 3));
softDrinkList .add(new SoftDrink("Frooti", "ColorThree", 2));
softDrinkList .add(new SoftDrink("Freshie", "ColorFour", 1));
Collections.sort(softDrinkList, new Comparator() {
#Override
public int compare(Object softDrinkOne, Object softDrinkTwo) {
//use instanceof to verify the references are indeed of the type in question
return ((SoftDrink)softDrinkOne).name
.compareTo(((SoftDrink)softDrinkTwo).name);
}
});
for (SoftDrink sd : softDrinkList) {
System.out.println(sd.name + " - " + sd.color + " - " + sd.volume);
}
Collections.sort(softDrinkList, new Comparator() {
#Override
public int compare(Object softDrinkOne, Object softDrinkTwo) {
//comparision for primitive int uses compareTo of the wrapper Integer
return(new Integer(((SoftDrink)softDrinkOne).volume))
.compareTo(((SoftDrink)softDrinkTwo).volume);
}
});
for (SoftDrink sd : softDrinkList) {
System.out.println(sd.volume + " - " + sd.color + " - " + sd.name);
}
}
}
In one line, using Java 8:
list.sort(Comparator.naturalOrder());
Unless you are sorting strings in an accent-free English only, you probably want to use a Collator. It will correctly sort diacritical marks, can ignore case and other language-specific stuff:
Collections.sort(countries, Collator.getInstance(new Locale(languageCode)));
You can set the collator strength, see the javadoc.
Here is an example for Slovak where Š should go after S, but in UTF Š is somewhere after Z:
List<String> countries = Arrays.asList("Slovensko", "Švédsko", "Turecko");
Collections.sort(countries);
System.out.println(countries); // outputs [Slovensko, Turecko, Švédsko]
Collections.sort(countries, Collator.getInstance(new Locale("sk")));
System.out.println(countries); // outputs [Slovensko, Švédsko, Turecko]
Use the two argument for of Collections.sort. You will want a suitable Comparator that treats case appropriate (i.e. does lexical, not UTF16 ordering), such as that obtainable through java.text.Collator.getInstance.
Here is what you are looking for
listOfCountryNames.sort(String::compareToIgnoreCase)
more simply you can use method reference.
list.sort(String::compareTo);
By using Collections.sort(), we can sort a list.
public class EmployeeList {
public static void main(String[] args) {
// TODO Auto-generated method stub
List<String> empNames= new ArrayList<String>();
empNames.add("sudheer");
empNames.add("kumar");
empNames.add("surendra");
empNames.add("kb");
if(!empNames.isEmpty()){
for(String emp:empNames){
System.out.println(emp);
}
Collections.sort(empNames);
System.out.println(empNames);
}
}
}
output:
sudheer
kumar
surendra
kb
[kb, kumar, sudheer, surendra]
You can use the following line
Collections.sort(listOfCountryNames, String.CASE_INSENSITIVE_ORDER)
It is similar to the suggestion of Thilo, but will not make a difference between upper and lowercase characters.
descending alphabet:
List<String> list;
...
Collections.sort(list);
Collections.reverse(list);
Java 8 ,
countries.sort((country1, country2) -> country1.compareTo(country2));
If String's compareTo is not suitable for your need, you can provide any other comparator.
Same in JAVA 8 :-
//Assecnding order
listOfCountryNames.stream().sorted().forEach((x) -> System.out.println(x));
//Decending order
listOfCountryNames.stream().sorted((o1, o2) -> o2.compareTo(o1)).forEach((x) -> System.out.println(x));
//Here is sorted List alphabetically with syncronized
package com.mnas.technology.automation.utility;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import org.apache.log4j.Logger;
/**
*
* #author manoj.kumar
*/
public class SynchronizedArrayList {
static Logger log = Logger.getLogger(SynchronizedArrayList.class.getName());
#SuppressWarnings("unchecked")
public static void main(String[] args) {
List<Employee> synchronizedList = Collections.synchronizedList(new ArrayList<Employee>());
synchronizedList.add(new Employee("Aditya"));
synchronizedList.add(new Employee("Siddharth"));
synchronizedList.add(new Employee("Manoj"));
Collections.sort(synchronizedList, new Comparator() {
public int compare(Object synchronizedListOne, Object synchronizedListTwo) {
//use instanceof to verify the references are indeed of the type in question
return ((Employee)synchronizedListOne).name
.compareTo(((Employee)synchronizedListTwo).name);
}
});
/*for( Employee sd : synchronizedList) {
log.info("Sorted Synchronized Array List..."+sd.name);
}*/
// when iterating over a synchronized list, we need to synchronize access to the synchronized list
synchronized (synchronizedList) {
Iterator<Employee> iterator = synchronizedList.iterator();
while (iterator.hasNext()) {
log.info("Sorted Synchronized Array List Items: " + iterator.next().name);
}
}
}
}
class Employee {
String name;
Employee (String name) {
this.name = name;
}
}

Categories

Resources