How to sort Arraylist in java - java

I have two different methods which fetch data from tow different DB tables. I will add both data into same ArrayList using bean class.
List<LeadVO> leadvoList = new ArrayList<LeadVO>(); // array list declaration
In the while loop I will load all the data using bean class. Before this action I will fire query for both tables.
while(true){
LeadVO statusVO = new LeadVO(); //initializing bean class
// code to load all value using setters
Finally I will add this bean to array list:
leadvoList.add(statusVO);
created seperate class to compare
public class ComparatorDAO implements Comparator {
public int compare(LeadVO arg0, LeadVO arg1) {
return arg1.getCreatedtimeFormat().compareTo(arg0.getCreatedtimeFormat()) ;
}
}
Collections.sort(commentVOList,new ComparatorDAO()); //sorting method
ideally this will not sort according to date i believe this will treat date as string
please help me in this
thanks once again
Now I need to sort this list in date order which is already present in the list. I mean the date which is present in the list.

If your LeadVO contains the date you want to sort by, implement Comparable interface in your VO and then sort the VO collection using Collections.sort().
public class LeadVO implements Comparable<LeadVO> {
private Date date;
// other properties, getters and setters
#Override
public int compareTo(LeadVO other) {
return date.compareTo(other.getDate());
}
}
and the sort like this:
Collections.sort(leadVoList);
You should ideally add null checks or use something like ObjectUtils.compare from commons-lang if your date is not guaranteed to be non-null.
Also you could do this by creating a Comparator instead of implementing Comparable as suggested by other posters, which might be better if you need to sort your VO by multiple values. If you just need to sort it by date, this approach might be a little simpler.

Here is the Example:Hope you don't mind hard interpretation.
List<String> unsortList = new ArrayList<String>();
unsortList.add("CCC");
unsortList.add("111");
unsortList.add("AAA");
unsortList.add("BBB");
unsortList.add("ccc");
unsortList.add("bbb");
unsortList.add("aaa");
unsortList.add("333");
unsortList.add("222");
//before sort
System.out.println("ArrayList is unsort");
for(String temp: unsortList){
System.out.println(temp);
}
//sort the list
Collections.sort(unsortList);
//after sorted
System.out.println("ArrayList is sorted");
for(String temp: unsortList){
System.out.println(temp);
}
}

You can sort arrayList using a comparator:
public Comparator<Record> RecordComparator = new Comparator<Record>() {
public int compare(Record record1, Record record2) {
return record1.getDate().compareTo(record2.getDate());
}
};
and then:
Collections.sort(list, new RecordComparator());

U'll need to override that class compareTo method as it is the method which java looks at for sorting
Simply override the fields that u need sorted
compareTo(Object other){Someclass.somefield.compareTo(other.smeField)}

Related

How do manipulate list of objects by date parameters in a hashmap?

I have a hashmap with key and object like
HashMap<String,List<Object,> > profileMap= new HashMap<>();
ArrayList eventList = new ArrayList();
for(Profile profile:Plist) {
> profileMap.putIfAbsent(profile.getprofileID(),eventList );
cpToEvent.get(event.getContact_profile()).add(event);
}
Profile object contains information about different events, event date, and profileID associated with that event.
I need to delete the events of the profile where the gap between two events in a profile is more than 1 yrs.
For that, I need to sort the list so that I can calculate the gap between them before deleting them.
How do achieve this?
If you are trying to have the elements in your List sorted, I recommend using a natively existing type such as a "SortedSet" implementation. E.g. a TreeSet
Map<String, TreeSet<Object>> profileMap = new HashMap<>();
This will have you implementing the Comparator Interface in which you can define to sort by Date.
public class Objekt implements Comparator<Objekt> {
#Override
public int compare(Objekt o1, Objekt o2) {
if (o1.getDate().before(o2.getDate())) {
return -1;
} else if (o1.getDate().after(o2.getDate())) {
return 1;
} else {
return 0;
}
}
More on how to implement that here: Compare Object by dates ( implements Comparator)
You can try to iterate over the HashMap item and filter the element with Date that is older than 1 year.
Given the Profile class as below
public class Profile {
private Date createdAt;
public Date getCreatedAt() {
return createdAt;
}
public void setCreatedAt(Date createdAt) {
this.createdAt = createdAt;
}
}
And our List is
HashMap<String, Profile> profiles = new HashMap<>();
Then we can simply do as below to get the list of Map.Entry that matches your requirement.
List<Map.Entry<String, Profile>> matchProfile = profiles.entrySet().stream().filter(item -> item.getValue().getCreatedAt().getYear() > 2015)
.collect(Collectors.toList());
There are several constraints you should have in mind, mostly regarding modifying your existing objects.
The simplest code that processes your items is this:
Map<String, List<Profile>> profileMap= ...;
profileMap.forEach((k, v) -> {
v.sort(Comparator.comparing(Profile::getDate));
// additional processing on "v" here (v is the value in the Map.Entry, i.e. the list of profiles)
});
But the code above modifies the List which exists in your map.
If you need to preserve the existing List as-is, then instead of sorting v, you should create a new List and then process that.
profileMap.entrySet().forEach(e -> {
List<Profile> profiles = new ArrayList<>(e.getValue());
profiles.sort(Comparator.comparing(Profile::getDate));
e.setValue(profiles);
});
The code above modifies the profileMap, it now maps the original keys to new values.
Again, if that is not ok, and you want to preserve the original profileMap entirely, then in the forEach above you need to fill a new Map instead of setValue-ing the existing entries.
Make sure to focus on solving or improving the overall product, not just on a small piece of the processing. Sometimes, the best way to improving a process is to eliminate some parts of it entirely and adjust the remaining pieces.
Why do you have a huge list of events that is both unsorted and containing obsolete entries? Can you sort the events when receiving them? Or when reading them from the database?

Sort List of Objects Based On Another Sorted List Object Positions In Java

I have two list objects like :
public class AttributeMaster {
public String attribute_id;
public String view_index;
...
}
List<AttributeMaster> attributes = new ArrayList<AttributeMaster>();
public class AttributeDetail {
public String attribute_id;
public String attribute_name;
...
}
List<AttributeDetail> attribute_detail = new ArrayList<AttributeDetail>();
Here, I need to sort attribute_detail list based on list attributes. List attribute is already sorted based on its view_index property.
I want to update second list based on index of attribute_master list.
If one one can help.
Collections.sort(attribute_detail,
Comparator.comparing(item -> attributes.indexOf(item)));
int start_index=0;
for(int i=0;i<attributes.size();i++) {
for(int j=0;j<attribute_detail.size();j++) {
if(attributes.get(i).getAttribute_id().equals(attribute_detail.get(j).getAttribute_id())){
AttributeDetail temp=attribute_detail.get(start_index);
attribute_detail.set(start_index, attribute_detail.get(j));
attribute_detail.set(j,temp);
start_index++;
}
}
}
Through index iterations, the code will check the object existence for both list using attribute_id. If the object present in both list, then it will sort the list of attribute_detail based on the index of attributes list.

Sort the array of String based on group of consatnt string count

I have a huge group of keys like more than 10L like the below in csv file
ABA,100
ABC,200
ABCs,50
ABM,65
ABMs,86
ABS,86
AC,54
ACLU,123
ACT,56
ACTH,154
AD,644
ADC,76
ADD,10.
Do I need to create the user define an object for the above key pairs? Will it create any memoery problem for creating more than 10L user define object?
My input String looks like [ABS,AC,ACLU,ABC]
I want the output AC,ABS,ACLU,ABC based on the count.
How to achieve it in easier way of Java 1.8.
Thanks.
You could add each line of your csv to a List<String> myList
Then, you will have to create a custom Comparator in order to sort your list based on the value, so something like the following,
private void customSorting(List<String> myList) {
Collections.sort(myList, (String s1, String s2) -> {
String valuePart1 = s1.split(",")[1];
String valuePart2 = s2.split(",")[1];
return Integer.valueOf(valuePart1).compareTo(Integer.valueOf(valuePart2));
});
}
Finally, just call your method like customSorting(myList); in any place of your code you need it
Of course, you have to modify the sorted list as well to keep only the first part (before comma) for each String value but that's easy.
An alternative could also be to create a class like the following,
public class MyClass {
private String key;
private String value;
// All the getters, setters, constructors, etc
}
, and then read each line of your csv, create an equivalent MyClass POJO and add it to a List<MyClass> myList.
You have to write your own custom Comparator again for List<MyClass> in a similar way like I did for the List<String>,
private void customSorting(List<MyClass> myList) {
Collections.sort(myList, (MyClass a, MyClass b) -> {
return Integer.valueOf(a.getValue()).compareTo(Integer.valueOf(b.getValue()));
});
}
Finally, create a new list from the sorted one by keeping only the keys

How can I sort my arraylist named "serviceNeedingTasks" based on two attributes of an object [duplicate]

I want to sort a List of objects by a specified attribute of those objects and I want to choose which attribute should be used for sorting. Example:
class Car{
private String name;
private String colour;
public enum sortBy {NAME, COLOUR};
public String name(){
return name;
}
public String colour(){
return colour;
}
public static Car[] getSortedArray(Car[] carArray, sortBy sortType){
HashMap<Object, Car> carMap = new HashMap<Object, Car>();
Object[] sortArray = new Object[carArray.length];
Object value = null;
for(int i = 0; i < carArray.length; i++){
if(sortType == sortBy.NAME){
value = carArray[i].name();
}else if(sortType == sortBy.COLOUR){
value = carArray[i].colour();
}
carMap.put(value, carArray[i]);
sortArray[i] = value;
}
Arrays.sort(sortArray);
Car[] sortedArray = new Car[sortArray.length];
for(int i = 0; i < sortArray.length; i++){
sortedArray[i] = carMap.get(sortArray[i]);
}
return sortedArray;
}
}
//external:
Car[] cars = getSomeCars();
Car[] nameSortedCars = Car.getSortedArray(cars, Car.sortBy.NAME);
Car[] colourSortedCars = Car.getSortedArray(cars, Car.sortBy.COLOUR);
The idea is simple:
I put all values that i want to sort by into an array, and i create a map that maps these values back to their objects. After I sorted this array I take the objects mapped to these values and put them in the same order into a new array which is then sorted by these values. The values are just created with type Object so I can sort by multiple types (not just Strings as in the example).
This works fine unless you have two objects with the same attribute value, then only one object will be in the returned array, but two times.
Is there a better way to achieve this sorting?
It would be much simpler to use custom comparators:
To sort by name:
Arrays.sort(carArray, Comparator.comparing(Car::name));
To sort by colour:
Arrays.sort(carArray, Comparator.comparing(Car::colour));
So you could modify getSortedArray():
public static Car[] getSortedArray(Car[] carArray, Comparator<Car> comparator) {
Car[] sorted = carArray.clone()
Arrays.sort(sorted, comparator);
return sorted;
}
And call it like this:
Car[] sorted = getSortedArray(carArray, Comparator.comparing(Car::name));
Edit:
If you use a language version that does not support these features, you can create the comparators by explicitly creating a nested class that implements the Comparator interface.
This, for example, is a singleton Comparator that compares Car instances by name:
static enum ByName implements Comparator<Car> {
INSTANCE;
#Override
public int compare(Car c1, Car c2) {
return c1.name().compareTo(c2.name());
}
}
Then call:
Car[] sorted = getSortedArray(carArray, ByName.INSTANCE);
TL;DR: There's already a wheel for that.
I would say the easiest way to do this is to create a comparator:
final Comparator<Car> byName = Comparator.comparing(Car::name);
final Comparator<Car> byColour = Comparator.comparing(Car::colour);
Then just use the appropriate method on Arrays to sort by a comparator:
Arrays.sort(carArray, byName);
Now you want to do it with an enum? Just have the enum implements Comparator<Car>:
enum SortBy implements Comparator<Car> {
NAME(Comparator.comparing(Car::name)),
COLOUR(Comparator.comparing(Car::colour));
private final Comparator<Car> delegate;
private SortBy(Comparator<Car> delegate) {
this.delegate = delegate;
}
#Override
public int compare(final Car o1, final Car o2) {
return delegate.compare(o1, o2);
}
}
Want to sort by name then by colour? Easy:
final Comparator<Car> byName = SortBy.NAME.thenComparing(SortBy.COLOUR);
Want to sort by name in reverse order? Easy:
final Comparator<Car> byName = SortBy.NAME.reversed();
You're reinventing the wheel! Life will be much easier for you if you use the templated Collections API. To do this, you would work with List instead of arrays, define a Comparator to do your sorting, and then let the API do the work for you.
Comparator<Car> carComparator = new Comparator<Car>(){
public int sort(Car car1, Car car2){
//Sorting logic goes here.
}
}
List<Car> cars = getCars();
cars = Collections.sort(cars, carComparator); //the cars collection is now sorted.
If you wanted to sometimes sort by one attribute or another, you could make my variable carComparator into its own class and define which attributes to sort by in the constructor.
Hope that helps :)
Edit: As others have pointed out, this approach also works with arrays. But unless you have a good reason to be working with Arrays, working with Collections will generally be easier.
I think the solution would be more efficient if you passed a Comparator implementation to the Arrays.sort. Right now, you are looping n*2 from the looks of it, the hash map (O(1)) plus the Arrays.sort (which is another 0(n log n) or such). If you do the below, you could skip the 2 loops, and the map, you are using currently.
You can simply create a Comparator like (rough code):
class CarComparator implements Comparator<Car> {
enum compareType; //plus setter
public int compareTo(Car a, Car b) {
if(compareType == COLOUR) return a.colour.compareTo(b.colour);
if(compareType == NAME.....
}
}
, and then simply send the array of Cars to
Arrays.sort(cars, new CarComparator(COLOUR))
, or use more specialised comparator classes, one for each attribute, and a factory to render them, and of course don't create a new Comparator() for each sort if this is happening often. :-)
Overall, this approach should make your code more efficient.
}

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