java: ArrayList how order [duplicate] - java

This question already has answers here:
How to sort List of objects by some property
(17 answers)
Closed 8 years ago.
I have this class:
public class Media {
double supporto;
double i_m;
String idSentence;
public Media(double supporto,double i_m,String idSent){
this.supporto=supporto;
this.i_m=i_m;
this.idSentence=idSent;
}
public double getSupporto(){
return this.supporto;
}
public double getI_m(){
return this.i_m;
}
public String getIdSentence(){
return this.idSentence;
}
public String toString(){
return this.supporto+" - "+this.i_m+" - "+this.idSentence;
}
}
and add in an ArrayList text these values​​:
ArrayList<Media> m=new ArrayList<Media>();
m.add(new Media(0.2545,0.2365,"id002"));
m.add(new Media(0.8745,0.4658,"id005"));
m.add(new Media(0.1599,0.6580,"id0010"));
How do I sort this array in descending order of the value of the first class Media?
I want to get this order:
0.1599,0.6580,"id0010"
0.2545,0.2365,"id002"
0.8745,0.4658,"id005"
EDIT
I solved this way:
public class Media implements Comparable<Object>{
double supporto;
double i_m;
String idSentence;
public Media(double supporto,double i_m,String idSent){
this.supporto=supporto;
this.i_m=i_m;
this.idSentence=idSent;
}
public double getSupporto(){
return this.supporto;
}
public double getI_m(){
return this.i_m;
}
public String getIdSentence(){
return this.idSentence;
}
public String toString(){
return this.supporto+" - "+this.i_m+" - "+this.idSentence;
}
#Override
public int compareTo(Object arg0) {
if(this.supporto==((Media) arg0).getSupporto()) return 0;
else if((this.supporto)>((Media)arg0).getSupporto()) return 1;
else return -1;
}
}
In the main method I order the m ArrayList:
Collections.sort(m);

You need to make Fruit Comparable
public class Media implements Comparable<Fruit> {
public int compareTo(Fruit compareFruit) {
int compareQuantity = ((Media) compareFruit).getSupporto();
//ascending order
return this.supporto - compareQuantity;
//descending order
//return compareQuantity - this.supporto;
}
...
}
Arrays.sort(m);
Some more info :
http://www.mkyong.com/java/java-object-sorting-example-comparable-and-comparator/

You can sort it with your own comparator
m.sort(new Comparator<Media>() {
#Override
public int compare(Media o1, Media o2) {
return Double.compare(o1.getSupporto(), o2.getSupporto());
}
});
this will sort it the way you like. If you need this in many pleaces, i would suggest however creating static comparator like:
private static Comparator<Media> supportoComparator = new Comparator<Media>() {
#Override
public int compare(Media o1, Media o2) {
if (o1 != null && o2 != null) {
return Double.compare(o1.getSupporto(), o2.getSupporto());
} else {
throw new IllegalArgumentException();
}
}
};
Above code is in class Media, and then you use it like:
m.sort(Media.GET_SUPPORTO_COMPARATOR());
and its done

Related

how to add/remove multiples of objects from an array list

I am trying to build an ArrayList that will contain objects. when i add an object to the list i want it to first check the array list for that object. and if it finds it i want it to increase a quantity variable in that object and not create a new object in the list. and then vice versa when removing objects. I have accomplished a way that works when removing an object. But i dont think i fully understand the methods in the arraylist or the logic when creating and arraylist of objects. as when i use .contains or .equals im not getting the desired effect.
public class ItemBag {
private ArrayList<Item> inventory = new ArrayList<Item>();
public ItemBag() {
}
public void addItem(Item objName, int quantity) {
if (inventory.contains(objName)) {
System.out.println("if statement is true!");
int i = inventory.indexOf(objName);
inventory.get(i).setQuantity(inventory.get(i).getQuantity() + quantity);
} else {
inventory.add(objName);
objName.setQuantity(quantity);
}
}
public void removeItems(String itemName, int quantiy) {
for (int i = 0; i < inventory.size(); i++) {
if (inventory.get(i).name() == itemName) {
inventory.get(i).setQuantity(inventory.get(i).getQuantity() - quantiy);
if (inventory.get(i).getQuantity() <= 0) {
inventory.remove(inventory.get(i));
}
}
}
}
public void showInventory() {
for (int i = 0; i < inventory.size(); i++) {
System.out.println(inventory.get(i).name() + " : " + inventory.get(i).getQuantity());
}
}
then when creating the itemBag in another object i am writing
ItemBag merchantItems = new ItemBag();
public void merchantBob() {
merchantItems.addItem(new HealthPotion() ,3);
merchantItems.showInventory();
System.out.println("add 1");
merchantItems.addItem(new HealthPotion(),1);
merchantItems.showInventory();
Items class
package Items;
public abstract class Item {
private int quantity = 0;
public Item() {
}
public abstract String name();
public abstract int cost();
public abstract String type();
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
}
HealthPotion Class
public class HealthPotion extends Potions {
protected int addHealth = 10;
#Override
public int drinkPotion() {
return addHealth;
}
#Override
public String name() {
return "Health Potion";
}
#Override
public int cost() {
return 5;
}
#Override
public String type() {
return "Potion";
}
}
The .contains() method would iterate through the list and use .equals() method to compare each element and check if the provided object exists in the list.
.equals() method would compare the object reference (unless .equals() is overridden) to check if the objects are same.
For reference: https://docs.oracle.com/javase/8/docs/api/java/util/Collection.html#contains-java.lang.Object-
You can override the .equals() method to compare the values of the provided object in the following way:
public abstract class Item {
private int quantity = 0;
public Item() {
}
public abstract String name();
public abstract int cost();
public abstract String type();
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
#Override
public boolean equals(Object object) {
if (this == object) return true;
if (object == null || getClass() != object.getClass()) return false;
Item providedItem = (Item) object;
return name == providedItem.name
&& cost == providedItem.cost
&& type == providedItem.type;
}
}
This should work

Sort Java list of objects

I need to sort a java list containing objects of type Hotel
List<Hotel> hotelList = new ArrayList<>();
Inside the class I do have the method
#Override
public List<Room> getAvailableRooms() {
return this.rooms;
}
I need to sort my hotelList by the price attribute found in Room class.
Any suggestions?
You should either use a Comparator or implement the Comparable interface
public class Foo implements Comparable<ToSort> {
private int val;
public Foo(int val){
this.val = val;
}
#Override
public int compareTo(ToSort f) {
if (val > f.val) {
return 1;
}
else if (val < f.val) {
return -1;
}
else {
return 0;
}
}
Read more here
https://dzone.com/articles/sorting-java-arraylist

Order arraylist based on multiple connection

This is my VO
public class SomeVO {
private String name;
private String usageCount;
private String numberofReturns;
private String trendNumber;
private String nonTrendNumber;
private String trendType;
private String auditType;
public SomeVO(String name,String usageCount,String numberofReturns,String trendNumber,String nonTrendNumber,String trendType,String auditType){
this.name = name;
this.usageCount = usageCount;
this.numberofReturns = numberofReturns;
this.trendNumber = trendNumber;
this.nonTrendNumber = nonTrendNumber;
this.trendType = trendType;
this.auditType = auditType;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUsageCount() {
return usageCount;
}
public void setUsageCount(String usageCount) {
this.usageCount = usageCount;
}
public String getNumberofReturns() {
return numberofReturns;
}
public void setNumberofReturns(String numberofReturns) {
this.numberofReturns = numberofReturns;
}
public String getTrendNumber() {
return trendNumber;
}
public void setTrendNumber(String trendNumber) {
this.trendNumber = trendNumber;
}
public String getNonTrendNumber() {
return nonTrendNumber;
}
public void setNonTrendNumber(String nonTrendNumber) {
this.nonTrendNumber = nonTrendNumber;
}
public String getTrendType() {
return trendType;
}
public void setTrendType(String trendType) {
this.trendType = trendType;
}
public String getAuditType() {
return auditType;
}
public void setAuditType(String auditType) {
this.auditType = auditType;
}
}
Here is my values
List<SomeVO> myList = new ArrayList<SomeVO>();
SomeVO some = new SomeVO("A","0","0","123","123","Trend","AuditX");
myList.add(some);
some = new SomeVO("B","1","1","234","234","Non trend","AuditX");
myList.add(some);
some = new SomeVO("C","0","2","345","345","Trend","AuditX");
myList.add(some);
some = new SomeVO("D","2","3","546","546","Trend","AuditX");
myList.add(some);
some = new SomeVO("E","2","4","678","678","Non trend","AuditX");
myList.add(some);
some = new SomeVO("F","0","0","123","123","Non trend","AuditA");
myList.add(some);
some = new SomeVO("G","0","0","123","123","Trend","AuditB");
myList.add(some);
Here is my comparator
public String currentAudit = "AuditX";
public class AuditComparator implements Comparator<SomeVO> {
#Override
public int compare(SomeVO o1, SomeVO o2) {
if(currentAudit.equalsIgnoreCase(o1.getAuditType()) && currentAudit.equalsIgnoreCase(o2.getAuditType())) {
int value1 = o2.getUsageCount().compareTo(o1.getUsageCount());
if (value1 == 0) {
int value2 = o1.getNumberofReturns().compareTo(o2.getNumberofReturns());
if(o1.getTrendType().equalsIgnoreCase("Trend") && o2.getTrendType().equalsIgnoreCase("Trend")) {
if (value2 == 0) {
return o1.getTrendNumber().compareTo(o2.getTrendNumber());
} else {
return value2;
}
} else {
if (value2 == 0) {
return o1.getNonTrendNumber().compareTo(o2.getNonTrendNumber());
} else {
return value2;
}
}
}
return value1;
} else {
return 1;
}
}
}
I am trying to sort the VO based on below conditions
First only set of values of currentAudit should be taken in to
consideration i.e., AuditX
a) then it should be sorted with
Usage count in descending order
b) if same usage count found then it
should be sorted with Return count in ascending order
c) if same
return count then it should check for trendType, if trendType
="Trend" then it should sort with Trend number otherwise nonTrend number.
then it should consider rest all auditType's and sorted with
a),b),c) condition as like currentAudit. I tried achieving it and i
ended up with only above comparator. Expected result: D, A, C, E,
F, G. But i get G,F,D,E,B,A,C. Please help me to update the
comparator above.
Your comparator does not meet a simple condition: it is not stateless. A following should always be true: A>B => B<A. In your case, in some scenarios A>B and B>A.
I resolved it by splitting the actual list in to 2 list based on AuditX and rest in another list. Then used below comparator one by one, and then merged in to a result list. Works good.
for(SomeVO some:myList) {
if(some.getAuditType().equalsIgnoreCase("AuditX")) {
auditX.add(some);
} else {
auditY.add(some);
}
}
Collections.sort(auditX, new AuditComparator());
Collections.sort(auditY, new AuditComparator());
public class AuditComparator implements Comparator<SomeVO> {
#Override
public int compare(SomeVO o1, SomeVO o2) {
int value1 = o2.getUsageCount().compareTo(o1.getUsageCount());
if (value1 == 0) {
int value2 = o1.getNumberofReturns().compareTo(o2.getNumberofReturns());
if (value2 == 0) {
return (o1.getTrendType().equalsIgnoreCase("Trend") && o2.getTrendType().equalsIgnoreCase("Trend")) ?
o1.getTrendNumber().compareTo(o2.getTrendNumber()):o1.getNonTrendNumber().compareTo(o2.getNonTrendNumber());
} else {
return value2;
}
}
return value1;
}
The return 1 at the bottom of the comparator makes a bug.
The comparator shall only return 1 if the second element is bigger than the first one, but if they're different, you always return 1, so the very first sorting criteria will be messy.
// a helper for case insensitive comparison
private int compareIgnoreCase(String o1,String o2) {
return o1.toLowercase.compareTo(o2.toLowercase());
}
#Override
public int compare(SomeVO o1, SomeVO o2) {
int result=compareIgnoreCase(o1.getAuditType(),o2.getAuditType());
if (result==0) {
// we need to go to the 2nd criteria
result=o2.getUsageCount().compareTo(o1.getUsageCount());
}
if (result==0) {
// ok, 1st and 2nd criteria was the same, go to the 3rd
result=o1.getNumberofReturns().compareTo(o2.getNumberofReturns());
}
if (result==0) {
// check trends
...
}
return result;
}
I found that this representation of multiple comparison criteria makes the code much easier to follow. We first do the highest priority of comparison, and go on with further comparions if the previous comparisons returned that the two elements are the same (i.e. result is still zero).
In case you need to make a descending sorting at some level, simply put a -, e.g.:
result=-o1.something.compareTo(o2.something)
It is a good idea to have only one exit point in a method (this also makes easier to follow what is happening).

How i can exclude a string when using comparator

Present i am using Comparator to sort my objects .I have the items in list as follows
FIRST ITEM
SECOND ITEM
THIRD ITEM
LAST ITEM
FORTH ITEM
Comparator code is:
public static Comparator<PartyResultVO> sortData = new Comparator<PartyResultVO>()
{
public int compare(VO vo1, VO vo2)
return (vo1.getName()).compareTo(vo2.getName());
};
It is working perfectly to sort.But what i want is i need to put the item with name LAST ITEM at last.How i can exclude only that object and place at the end.Is there any way to do that.
Please help me.Thanks in advance...
You can just add special logic for that case:
public static Comparator<VO> sortData = new Comparator<VO>()
{
public int compare(VO vo1, VO vo2) {
if (vo1.getName().equals("LAST ITEM")) {
if (vo2.getName().equals("LAST ITEM")) {
return 0;
} else {
return 1;
}
else if (vo2.getName().equals("LAST ITEM")) {
return -1;
}
return (vo1.getName()).compareTo(vo2.getName());
}
};
Can you try this ?
Collections.sort(list, new Comparator<PartyResultVO>() {
#Override
public int compare(VO vo1, VO vo2) {
if (vo1.getName().equals("LAST ITEM")) {
if (vo2.getName().equals("LAST ITEM")) {
return 0;
} else {
return 1;
}
else if (vo2.getName().equals("LAST ITEM")) {
return -1;
}
return vo1.getName().compareTo(vo2.getName());
}
});
You could introduce state to your comparator and make it work exceptionally with certain values, return an integer that guarantees it will be the last one. Extended example of Keppil's comparator:
class PartyResultComparator implements Comparator<PartuResultVO> {
String exceptionalValue;
public PartyResultComparator(String exceptionalValue) {
this.exceptionalValue = exceptionalValue;
}
public int compare(VO vo1, VO vo2) {
if (isExceptional(vo1.getName())) {
return 1;
else if (isExceptional(vo2.getName())) {
return -1;
}
return (vo1.getName()).compareTo(vo2.getName());
}
private boolean isExceptional(String value) {
// is this value exceptional?
}
}
A shorter implementation
public static Comparator<PartyResultVO> sortData = new Comparator<PartyResultVO>() {
public int compare(VO vo1, VO vo2) {
return mapToLast(vol.getName()).compareTo(mapToLast(vo2.getName()));
}
String mapToLast(String s) {
return s.contains("LAST") ? "\uFFFF" : s;
}
}

sort custom Array List

I have a class called x which is a array list and needs to be sorted in Decreasing order by Value.
My Class-
public static class x
{
public int id;
public double value;
public x(int _id, double _value)
{
id = _id;
value = _value;
//System.out.println(Integer.toString(id));
}
public Integer getID(){
return id;
}
public double getValue(){
return value;
}
//Sorting
public static Comparator<x> getComparator(SortParameter... sortParameters) {
return new xComparator(sortParameters);
}
public enum SortParameter {
VAL_DESCENDING
}
private static class xComparator implements Comparator<x> {
private SortParameter[] parameters;
private xComparator(SortParameter[] parameters) {
this.parameters = parameters;
}
public int compare(x o1, x o2) {
int comparison;
for (SortParameter parameter : parameters) {
switch (parameter) {
case VAL_DESCENDING:
comparison = o2.id - o1.id;
if (comparison != 0) return comparison;
break;
}
}
return 0;
}
}
}
I Call it like:
cp = x.getComparator(x.SortParameter.VAL_DESCENDING);
Collections.sort(attr1, cp);
attr1 is my array list
Just for Reference I am following this
I am getting error:
cannot find symbol : variable cp
I am a newbie to java :(
try using Comparator<x> cp = x.getComparator(x.SortParameter.VAL_DESCENDING); to declare it. you can not use a variable until it is declared

Categories

Resources