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
Related
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
I have a task to implement a collection of elements in ascending order, along with methods of adding an element to the collection, printing all the elements in the collection and loading an element (along with removing it from the collection, I can assume that I'm always loading the smallest one).
I'm supposed to use Comparable<T> interface.
Additionally, I need to implement a class hierarchy with the use of Comparable<T> interface (for example, it can be a hierarchy of military ranks).
Here is my code:
public class Collection<T extends Comparable<T>> implements Iterable<T>
{
public LinkedList<T> collection;
public Collection()
{
collection = new LinkedList<>();
}
public void addToList(T new)
{
int i = 0;
while (collection .get(i).compareTo(new) < 0)
{
i++;
}
collection.add(i, new);
}
public T load() throws EmptyStackException
{
if (collection.size() == 0)
{
throw new EmptyStackException();
}
T first = collection.getFirst();
collection.removeFirst();
return first;
}
public void printElements()
{
for (T obj : collection)
{
System.out.println(obj);
}
}
#Override
public Iterator<T> iterator()
{
return this.collection.iterator();
}
}
public abstract class Soldier implements Comparable<Soldier>
{
public String Name;
public abstract double Rank();
public int compareTo(Soldier S)
{
if(S.Rank() == this.Rank())
{
return 0;
}
else if (S.Rank() < this.Rank())
{
return 1;
}
else return -1;
}
}
public class General extends Soldier
{
public double Rank()
{
return 4;
}
public General(String Name)
{
this.Name = Name;
}
}
public class Colonel extends Soldier
{
public double Rank()
{
return 3;
}
public Colonel(String Name)
{
this.Name = Name;
}
}
public class Corporal extends Soldier
{
public double Rank()
{
return 2;
}
public Corporal(String Name)
{
this.Name = Name;
}
}
public class Private extends Soldier
{
public double Ranga()
{
return 1;
}
public Private(String Name)
{
this.Name = Name;
}
}
When I tried to run some tests I got an error "Index out of bounds". What is actually happening here? I suspect that I can't add an element to my collection properly. Is this code correct?
The problem can be isolated here:
public LinkedList<T> collection;
public Collection()
{
collection = new LinkedList<>();
}
public void addToList(T new)
{
int i = 0;
while (collection.get(i).compareTo(new) < 0)
{
i++;
}
collection.add(i, new);
}
The first time you try to add an element, you pass zero to collection.get. This attempts to get the first element (as Lists are zero-indexed) but there is no first element to get.
Additionally, 'new' is a keyword in Java and cannot be used as an identifier.
Your problem lies in this loop
while (collection .get(i).compareTo(new) < 0)
{
i++;
}
It will try to get a new element even if i is equal to or greater than the length of the collection. You need to check that it is not.
while (i < collection.size() && collection .get(i).compareTo(new) < 0)
{
i++;
}
I want to sort a vector based on user defined order.
here is my code snippet
class xxx {
private String xxName;
private String xxMapName
//getters and setter
}
// main
public class Test {
public static void main(String s) {
List<xxx> options = new Vector<xxx>();
scenarion1: (IF vector contains ISE_BASE,ISE_ADVANCED,ISE)
xxx x1 = new xxx();
x1.setXxName("s1");
x1.setXxMapName("ISE_BASE");
options.add(x1);
xxx x2 = new xxx();
x2.setXxName("s1");
x2.setXxMapName("ISE_ADVANCED");
options.add(x2);
xxx x2 = new xxx();
x2.setXxName("s1");
x2.setXxMapName("ISE");
options.add(x2);
scenarion2:(IF vector contains any two of ISE_BASE,ISE_ADVANCED,ISE)
xxx x1 = new xxx();
x1.setXxName("s1");
x1.setXxMapName("ISE_BASE");
options.add(x1);
xxx x2 = new xxx();
x2.setXxName("s1");
x2.setXxMapName("ISE_ADVANCED");
options.add(x2);
}
}
I want to sort vector based on xxMapName(property of xxx). Here the order should be always ISE_BASE,ISE,ISE_ADVANCED.
You can implement comparator interface and use
Collections.sort(List<T> list, Comparator<? super T> c)
Override compareTo()
class xxx implements Comparable<xxx> {
private String xxName;
private String xxMapName
//getters and setter
public int compareTo(xxx obj) {
if (this.xxMapName.equals("ISE_BASE")) {
return -1;
} else if (obj.xxMapName.equals("ISE_BASE")) {
return 1;
} else if (this.xxMapName.equals("ISE")) {
return -1;
} else if (obj.xxMapName.equals("ISE")) {
return 1;
} else if (this.xxMapName.equals("ISE_ADVANCED")) {
return -1;
} else if (obj.xxMapName.equals("ISE_ADVANCED")) {
return 1;
}
return 0;
}
}
after which you can use Collections.sort(options)
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;
}
}
I've got a public List<FriendProfile> friends = new ArrayList<FriendProfile>();. I initialize the friends list by reading the information from the server. The FriendProfile object contains a int called private int userPosition;
Once the friends list has been initialized, I would like to sort the friends list by having the FriendProfile object with the highest userPosition at index 0 of the list and then sort by accordingly, index 1 with the second highest userPosition ...
I guess I could write an sorting algorithm, yet I'm looking for prewritten code (maybe the JDK has some methods to offer?)
Help is appreciated!
Use Collections.sort() and specify a Comparator:
Collections.sort(friends,
new Comparator<FriendProfile>()
{
public int compare(FriendProfile o1,
FriendProfile o2)
{
if (o1.getUserPosition() ==
o2.getUserPosition())
{
return 0;
}
else if (o1.getUserPosition() <
o2.getUserPosition())
{
return -1;
}
return 1;
}
});
or have FriendProfile implement Comparable<FriendProfile>.
Implement Comparable Interface.
class FriendProfile implements Comparable<FriendProfile> {
private int userPosition;
#Override
public int compareTo(FriendProfile o) {
if(this.userPosition > o.userPosition){
return 1;
}
return 0;
}
}
Just Call the Collection.sort(List) method.
FriendProfile f1=new FriendProfile();
f1.userPosition=1;
FriendProfile f2=new FriendProfile();
f2.userPosition=2;
List<FriendProfile> list=new ArrayList<FriendProfile>();
list.add(f2);
list.add(f1);
Collections.sort(list);
The List will be sorted.
Now no need to Boxing (i.e no need to Creating OBJECT using new Operator use valueOf insted with compareTo of Collections.Sort..)
1)For Ascending order
Collections.sort(temp, new Comparator<XYZBean>()
{
#Override
public int compare(XYZBean lhs, XYZBean rhs) {
return Integer.valueOf(lhs.getDistance()).compareTo(rhs.getDistance());
}
});
1)For Deascending order
Collections.sort(temp, new Comparator<XYZBean>()
{
#Override
public int compare(XYZBean lhs, XYZBean rhs) {
return Integer.valueOf(rhs.getDistance()).compareTo(lhs.getDistance());
}
});
Use Collections.Sort and write a custom Comparator that compares based on userPosition.
use Comparator with Collections.sort method
java.util.Collections.sort(list, new Comparator<FriendProfile >(){
public int compare(FriendProfile a, FriendProfile b){
if(a.getUserPosition() > b.getUserPosition()){
return 1;
}else if(a.getUserPosition() > b.getUserPosition()){
return -1;
}
return 0;
}
});
see this link
There are two ways to do this.
1.
FriendProfile could implement the interface Comparable.
public class FriendProfile implements Comparable<FriendProfile>
{
public int compareTo(FriendProfile that)
{
// Descending order
return that.userPosition - this.userPosition;
}
}
...
Collections.sort(friendProfiles);
2.
You could write a Comparator.
public class FriendProfileComparator implements Comparator<FriendProfile>
{
public int compare(FriendProfile fp1, FriendProfile fp2)
{
// Descending order
return fp2.userPosition - fp1.userPosition;
}
}
...
Collections.sort(friendProfiles, new FriendProfileComparator());
When comparing objects rather than primitives note that you can delegate on to the wrapper objects compareTo. e.g. return fp2.userPosition.compareTo(fp1.userPosition)
The first one is useful if the object has a natural order that you want to implement. Such as Integer implements for numeric order, String implements for alphabetical. The second is useful if you want different orders under different circumstances.
If you write a Comparator then you need to consider where to put it. Since it has no state you could write it as a Singleton, or a static method of FriendProfile.
You can use java.lang.Comparable interface if you want to sort in only One way.
But if you want to sort in more than one way, use java.util.Compartor interface.
eg:
The class whose objects are to be Sorted on its roll_nos
public class Timet {
String name;
int roll_no;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getN() {
return roll_no;
}
public void setN(int n) {
this.roll_no = n;
}
public Timet(String name, int n) {
this.name = name;
this.roll_no = n;
}
public String toString(){
return this.getName();
}
}
The class for sorting:
public class SortClass {
public void go(){
ArrayList<Timet> arr = new ArrayList<Timet>();
arr.add(new Timet("vivek",5));
arr.add(new Timet("alexander",2));
arr.add(new Timet("catherine",15));
System.out.println("Before Sorting :"+arr);
Collections.sort(arr,new SortImp());
System.out.println("After Sorting :"+arr);
}
class SortImp implements Comparator<Timet>{
#Override
public int compare(Timet t1, Timet t2) {
return new Integer(t1.getN()).compareTo (new Integer((t2.getN())));
}
}
public static void main(String[] args){
SortClass s = new SortClass();
s.go();
}
}