Sort a data structure in Java [duplicate] - java

This question already has answers here:
sorting objects in java
(6 answers)
Closed 6 years ago.
I have a data structure in Java which looks like:
class Order {
int id;
String name;
int totalCost;
String address;
List<String> items;
public setter() {
....
}
public getter() {
...
}
}
I have a test class which uses this data structure:
class TestClass {
List<Order> o = getAllOrders();
sortOrders();
}
I want to write a sortOrders method to sort this this data structure based on one of its attributes, in this case the name on the order.
I know to sort in Java we can do:
java.util.Collections.sort(anyArrayListOfStrings);
What is the efficient way to sort the whole data structure in Java?

Well, all you would need is to pass a comparator to the Collections.sort() method. You could do something like this since you want to sort the list of Order objects based on the name field..
Collections.sort(o, new Comparator<Order>() {
public int compare(Order o1, Order o2) {
return o1.name.compareTo(o2.name);
}
});

Related

objectmapper only serialize specific fields [duplicate]

This question already has answers here:
How do I use a custom Serializer with Jackson?
(11 answers)
Closed 1 year ago.
I want to write a function that only serializes a POJO with given implicit field names.
For example,
class Car{
public int id;
public String type;
public Manufacture manufacture;
}
Class Manufacture{
public int id;
public String name;
}
if I want to serialize a Car object with a given list(i.e. [Car.id, Car.Manufacture.name])
Then I want to get
{
Car:{
id: xxx,
Manufacture: {
name: xxx
}
}
}
Another example, given list = [Car.type]
Then I should get
{
Car:{
type: xxx
}
}
I am currently trying to override the serializeAsField method to check if the field is in the given list, but the problem here is that I don't know the depth, then I cannot correctly compare the current field with the list.
How could I achieve it? Are there any other ways?
Mark the unwanted fields with the #JsonIgnore annotation.
On-the-fly filtering
Here is a Baeldung article that discusses using a filter to
determine which fields are serialized:
https://www.baeldung.com/jackson-serialize-field-custom-criteria
I suspect that is the answer you want.

Sort ArrayList of Objects by Specific Element

I have several arraylists which each contain player data for a specific team. Each object contains the following elements in order; Jersey Number, First Name, Last Name, Preferred Position, Goals, Assists. The user decides whether to view the data by goals or assists, and then the data is displayed in descending order. Goals and assists are both of int data type.
I will be able to display the data fine but what I am stuck on is how to sort the arrayList by one of these specific stats. Because the data from all the teams is in different arrayLists, and need to be sorted all together, do I need to combine the arrayLists into one master arrayList that will be sorted? As for the sorting, I have done a bit of research and it looks like I need to use a comparator? Could someone provide some assistance with this because I have never used these before and am quite lost. Examples would be great.
I have attached a few code snippets to hopefully provide some clarity.
ArrayList <blackTeam> blackTeam = new ArrayList <blackTeam>();
ArrayList <blueTeam> blueTeam = new ArrayList <blueTeam>();
ArrayList <greenTeam> greenTeam = new ArrayList <greenTeam>();
ArrayList <orangeTeam> orangeTeam = new ArrayList <orangeTeam>();
ArrayList <redTeam> redTeam = new ArrayList <redTeam>();
ArrayList <yellowTeam> yellowTeam = new ArrayList <yellowTeam>();
private void displaystatButtonActionPerformed(java.awt.event.ActionEvent evt) {
//sort arrayList by goals/assists
}
EDIT:
This is how my classes are set up, as well as how data is added to them. Hopefully this clears up some questions.
//add data to database
black = new blackTeam(jerseyNum, firstName, lastName, prefPosition, goals, assists);
blackTeam.add(black);
class blackTeam {
int goals, assists;
String jerseyNum, firstName, lastName, prefPosition;
blackTeam (String _jerseyNum, String _firstName, String _lastName, String _prefPosition, int _goals, int _assists) {
jerseyNum = _jerseyNum;
firstName = _firstName;
lastName = _lastName;
prefPosition = _prefPosition;
goals = _goals;
assists = _assists;
}
}
I have one these classes for each team.
I suggest using Comparator on your object, let me assume it is Team
public class Team{
private int jerseyNumber;
private String lastName;
...
public int getJerseyNumber(){
return jerseyNumber;
}
}
If you want to sort based on jersey number, generate JeseryNumberComaparator:
import java.util.Comparator;
public class JeseryNumberComaparator implements Comparator {
#Override
public int compare(Team t1, Team t2) {
// descending order (ascending order would be:
// t1.getJerseyNumber()-t2.getJerseyNumber())
return t1.getJerseyNumber()-t2.getJerseyNumber()
}
}
It will sort your list based on jersey number by:
Collections.sort(blackTeam, new JerseyNumberComparator());
For sorting Collection in Descending order (other than their natural sort order), you have to define your own Comparator.
For sorting on a specific field individually (one at a time), you have to define separate Comparator implementation.
In your class, you can define two individual Comparators. Here is example code.
static final Comparator<Team> SORT_TEAM_BY_GOALS_DESCENDING = new Comparator<Team>(){
public int compare(Team t1, Team t2){
return t2.getGoals() - t1.getGoals();
}
}
static final Comparator<Team> SORT_TEAM_BY_ASSIST_DESCENDING = new Comparator<Team>(){
public int compare(Team t1, Team t2){
return t2.getAssist() - t1.getAssist();
}
}
Make sure that, normal sort is always natural order, in your case for int it is always Ascending. In order to have Descending order, you need to do t2 - t1. t1 - t2 will give you natural Ascending order.
Now in order to use this Comparator, just use following code.
Collections.sort(team, SORT_TEAM_BY_GOALS_DESCENDING);
or
Collections.sort(team, SORT_TEAM_BY_ASSIST_DESCENDING);
And off course, if all these different color List (i.e. blackTeam and so on) are only for specific team identified by color, than add one more field to your Team class called 'color` which will identify each player along with what team they belongs to.
As long as your 6 classes blackTeam to yellowTeam all descend from the same parent, ie. that they are declared like this:
public class blackTeam extends Team { ... }
then you can make a new ArrayList<Team> and add them all to it:
ArrayList<Team> all = new ArrayList<>();
all.addAll(blackTeam);
all.addAll(blueTeam);
all.addAll(yellowTeam);
// etc...
Then you can sort this list using an instance of Comparator<Team>. Since Java8, however, there's a much neater way to create a comparator using lambda expressions:
all.sort((a, b) -> a.getScore() - b.getScore()); // or whatever attribute you want to compare on
If you want to do it the old fashioned way instead, then you can create an anonymous class like this:
all.sort(new Comparator<Team>() {
#Override
public int compare(Team a, Team b) {
return a.getScore() - b.getScore();
}
});
They amount to the same thing, but the lambda based approach is a bit less wordy!
Note that i suspect you don't actually want to have 6 different classes for the different colours. Are you sure you have understood the role of a class properly?

using set or List here in the code

I am newbie to java, I have a scenario, where i need to list the organisation types from the table:
Requirement : Just listing, no add or removing the elements,
As i understand the difference between set and list:
Set:
Set is Unique collection of Objects.
Set is Un-ordered collection of Objects.
List:
List is non-unique collection of Objects.
List is ordered collection of Objects.
In my table i am having columns like:
id name is_active
1 Lab 1
2 Pharmacy 2
3 Hospital 3
Maximum 10 rows
**Controller**:
List<OrgType> orgTypeList = organizationService.getAllOrgTypes(true);
OrgTypeResponse response = new OrgTypeResponse();
List<EntityDetail> orgTypeDetailList = new ArrayList<>();
EntityDetail orgTypeDetail;
for(OrgType orgType : orgTypeList) {
orgTypeDetail = new EntityDetail();
orgTypeDetail.setId(orgType.getId());
orgTypeDetail.setName(orgType.getName());
orgTypeDetailList.add(orgTypeDetail);
}
response.setStatus(ResponseStatusCode.SUCCESS);
response.setTotalOrgTypes((long)orgTypeDetailList.size());
response.setOrgTypes(orgTypeDetailList);
return response;
**Service** Implementaion:
List<OrgType> orgTypeList = orgTypeRepository.findByActive(active);
return orgTypeList;
This is my EntityDetail class:
public class EntityDetail {
private Long id;
private String name;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
My question here is, can i use the Set instead of List
If Set is used, can i use TreeSet, because i need to show in the asc order of id
Or Leave the code, as it is
i just want the clarification,
Thanks
You can use any of them but things to be kept in consideration:
Set although provides unique data, but that also has a cost.
In case, you are sure that table has unique names of organizations then you should opt for list.
It seems like you are using Spring with JPA, if that is the case, then you can use SORT interface(org.springframework.data.domain.Sort) to get sorted data.
My question here is, can i use the Set instead of List
Yes, without problem, just implement methods equals and hashCode.
If Set is used, can i use TreeSet, because i need to show in the asc order of id
You can if class EntityDetail implements interface Comparable<EntityDetail>. This is necessary because TreeSet must know what is the natural order of the various EntityDetail objects.
For more details please see Oracle docs on object ordering and Javadoc for Comparable
yes u can use SET instead of List in this scenario because SET will ensure that duplicate entries are eliminated. But making use of SET make sure that you have overridden "equals" and "hashcode" appropriately.
This is how you need to override equals and hashcode methods and for sorting purpose you need to implement Comparable and implement compareTo method as follows:
class EntityDetail implements Comparable<EntityDetail>{
#Override
public int hashcode(){
int result = 17;
result = 31 * result + name.hashCode();
result = 31 * result + id;
return result;
}
#Override
public boolean equals(Object o){
if (o == this) return true;
if (!(o instanceof EntityDetail)) {
return false;
}
EntityDetail ed = (EntityDetail) o;
return ed.name.equals(name) &&
ed.id == id ;
}
#Override
public int compareTo(EntityDetail ed) {
int compareId = ((EntityDetail) ed).getId();
//ascending order
return this.id - compareId;
//descending order
//return compareId - this.id;
}
}
You can use List if you can make sure in your code that the details are added in it in the order that you want. If you are not sure of the order in which you add then you can use the Collections.sort method. For this you will also want to make your OrgType implement the Comparable interface to provide a strategy to order the OrgType objects. In your case it is by id.
If you use TreeSet, the sorting is done automatically whenever you insert into the set thereby eliminating the use of Collections.sortbut you will still have to provide an ordering strategy.
Have a look at this
There are costs of using a Set because it maintains unique elements but because you have a maximum of 10 rows that won't be a problem.

Converting an array into Array List [duplicate]

This question already has answers here:
Create ArrayList from array
(42 answers)
Closed 6 years ago.
Hi I have two Java Files as below:
case 6:
System.out.println("List All Property Details For Rent >>>");
// System.out.println(Arrays.toString(Property_list));
int i=0;
while(i<count){
ppty.property_list[i].viewPropertyDetails("RENT");
i++;
}
System.out.println("++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
break;
}
}
}
}
Guys, This is basically an array of properties, and a Menu to do some operation with the list. I was planning to improve my code with a java ArrayList, because its more dynamic in nature. Could anyone tell me how I can convert this array (property_list) into an ArrayList? What are the changes do I need to make? Thanks in advance.
Your commented code is perfectly valid for initiliazing the arrayList.
ArrayList<Property> property_list = new ArrayList<Property>();
In java 7 or later you don't need to specify the second Property:
ArrayList<Property> property_list = new ArrayList<>();
Unlike the java Array you don't use bracket notation to access your variables you use .get(int index):
ppty.property_list.get(count)
To add a value you use .add(Object item);
ppty.property_list.add(new Property());
And you don't need to remember the size of ArrayList by storing it in a variable. The ArrayList has the .size() method which returns the number of elements in it.
Extra tips:
Here you can find extra methods the ArrayList has https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html
You have setters and getters in your Property object. You could set the member variables to private and use them.
You should replace that ppty method with the constructor method like so:
public Property(int streetno,String streetname,
String suburb,
int postalcode,String contactperson,
String office,int phonenumber,
String openTime,String propertytype,
double price, String date){
this.StreetNumber = streetno;
this.StreetName=streetname;
this.Suburb=suburb;
this.PostalCode=postalcode;
this.ContactPerson=contactperson;
this.PhoneNumber=phonenumber;
this.Office=office;
this.OpenTime=openTime;
this.PropertyType=propertytype;
this.PropertyPrice=price;
this.Date = date;
}
This property_list should not be inside your Property object. This is something you should handle outside the object. For example in your public void displayMenuPanel() you could say ArrayList<Property> properties = new ArrayList<>(). If you put the list inside the object then it is tied with that object. If the object goes, the list goes.

Java : How to store Integer and String in array and retrieve values in another class? [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I have a model: fase.java with Integers and Strings + getters and setters:
public class Fase implements Serializable {
private Integer age;
private String name;
}
I want to store both the Integer and String in a Array or ArrayList. I now use this:
public String[] getAllValues(){
String[] values = {age.toString(), name};
return values;
Then in dataServiceImpl.java I retrieve the data with:
user.getFase().getAllValues()[0];
and retrieve the age.
This works, but I have a lot more than age and name, and was thinking if I could put everything in Fase.java in one Array/ArrayList, because they are Integer and String, and then retrieve it in dataServiceImpl.java?
Something like this in Fase.java: ArrayList <Objects> f3Values = new ArrayList <Objects>();
or Fase [] f3Array = new Fase[34];
and then retrieve that in dataServiceImpl.java with: ArrayList<Fase3.Fase3Array> f3List = new ArrayList<Fase3.Fase3Array>();
and use something like: user.f3List[0]; ?
First, you should learn how Java works.
Is Java "pass-by-reference" or "pass-by-value"?
http://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
Then, you should learn how to properly create an encapsulated class, by defining both constructor(s) and getters, methods, setters (if needed; note that setters in general break encapsulation) etc.
Then, you should understand that to aggregate data you:
create a class, i.e. definition object that holds all the necessary fields,
create a storage aggregate (array, ArrayList, Map, whatever),
3a. create an object of a given class, setting the values of the fields,
3b. add the object to the aggregate,
3c. goto 3a until the aggregate is filled with the data needed.
Explaining that on the code provided, you should first have
public class Fase implements Serializable {
private int age;
private String name;
public Fase( int age, String name ) {
this.age = age;
this.name = name;
}
public int getAge() { return age; }
public String getName() { return name; }
}
then you can create the aggregate, e.g.
int FASE_MAX = 34;
Fase[] fArray = new Fase[FASE_MAX];
ArrayList<Fase> fArrayList = new ArrayList<Fase>(FASE_MAX);
then you create the objects and add them to the aggregate, e.g.
for( int i = 0; i < FASE_MAX; i++ ) {
Fase newFase = new Fase( i, "John Doe" );
fArrayList.add( newFase );
fArray[i] = newFase;
}
then, and only then, you can access the aggregate:
Fase someFase = fArrayList.get( n );
Fase someOtherFase = fArray[n];
Your Fase class can have whatever members and however many members you like and you can access them all. If you want an array of Fase then create one and each element of the array will contain all the Fase members.
Fase[] myArray = new Fase[34];
You have an array of 34 "Fase's" just add whatever members you want to your Fase class.

Categories

Resources