How i can exclude a string when using comparator - java

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;
}
}

Related

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).

HashMap and ArrayList order

I have HashMap and ArrayList I am adding data wih following code:
conversationsMap.put(sendName,new Conversation(receiverName,currentTime));
conversationsList=new ArrayList<Conversation>(conversationsMap.values());
I have an method for get currentTime like this:
conversation.getTime();
I want to order conversationsList by currentTime with this code they are not ordering.conversationsList should be like this:
1)currentTime:10
2)currentTime:9
2)currentTime:8
...
How can i achive this ? I guess I need to use a loop for get values then add to conversationsList
private class CustomComparator<T extends Conversation> implements Comparator<Conversation>{
public int compare(Conversation loBean1, Conversation loBean2) {
if(obj1.getTime()<obj2.getTime()) {
return -1;
} else if(obj1.getTime()>obj2.getTime()) {
return 1;
} else {
return 0
}
}
}
Collections.sort(conversationsList, new CustomComparator<Conversation>());
You can also implement the Comparable Interface.. And do something like this.
public class Conversation implements Comparable<Conversation>
{
int currentTime;
public int getCurrentTime()
{
return currentTime;
}
public void setCurrentTime(int currentTime)
{
this.currentTime = currentTime;
}
#Override
public int compareTo(Conversation o)
{
int ret = 0;
if (this.currentTime > o.getCurrentTime())
{
ret = 1;
}
else if (this.currentTime < o.getCurrentTime())
{
ret = -1;
}
return ret;
}
}
if you need to use it in one place then you may create the comparator on fly
conversationsMap.put(sendName,new Conversation(receiverName,currentTime));
conversationsList=new ArrayList<Conversation>(conversationsMap.values());
Collections.sort(conversationsList, new Comparator<Conversation>()
{
#Override
public int compare(Conversation obj1, Conversation obj2)
{
if(obj1.getTime()<obj2.getTime()) {
return -1;
} else if(obj1.getTime()>obj2.getTime()) {
return 1;
} else {
return 0
}
}
});
which is some time convenient for small task. but if you are writing big project and long time code maintaining is there. you might use the previous answer provided.
for quick solution:

java: ArrayList how order [duplicate]

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

Removing from a MultiSet

So I've been tasked to create a method to remove an element from a MultiSet. I've been trying for a while, but sadly in vain. My code is as follows:
import java.util.*;
public class MultiSet<E> extends AbstractCollection<E> {
private HashMap<E, Integer> elements;
private int noOfElems;
public MultiSet() {
elements = new HashMap<E, Integer>();
noOfElems= 0;
}
public MultiSet(Collection<E> c) {
this();
addAll(c);
}
public int size() {
return noOfElems;
}
public Iterator<E> iterator() {
return new Iterator<E>() {
Iterator<E> iterator = elements.keySet().iterator();
int elemsLeft = 0;
E thisElem = null;
public boolean hasNext() {
return iterator.hasNext();
}
public E next() {
if (elemsLeft == 0) {
thisElem = iterator.next();
elemsLeft = elements.get(thisElem);
}
elemsLeft -= elemsLeft;
return null;
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
public boolean add(E e) {
Integer i = elements.get(e);
if(i == null) {
i = 1;
} else {
i += 1;
}
elements.put(e, i);
noOfElems++;
return true;
}
public String toString() {
return elements.toString();
}
public int hashCode() {
return elements.hashCode();
}
public boolean equals(MultiSet<E> other) {
if (this == other) {
return true;
}
if (other == null) {
return false;
}
if (this.getClass() != other.getClass()) {
return false;
}
MultiSet<?> obj = (MultiSet<?>) other;
return obj.elements.equals(elements);
}
public boolean remove(Object o) {
}
}
And I want to implement the remove method. Anything that will help me, even a few pointers on where to start, will be greatly appreciated. Thanks! (also, comments on the rest of my code will also be appreciated)
This multiset just stores the elements as hash keys mapped to a count of the number of occurrences. To remove all instances of an element, just delete the key:
public void remove_all(E e) {
elements.remove(e);
}
If you need to remove only one instance, then decrement the count unless it's already a 1. In that case, remove the key.
public void remove(E e) {
Integer i = elements.get(e);
if (i != null) {
if (i == 1) {
elements.remove(e);
} else {
elements.put(e, i - 1);
}
}
}
BTW it's a bit hard to believe this is your code. If you understand enough to write the methods you've already written, how could you not know even where to start on remove?

Categories

Resources