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:
Related
In my scenario, we offer multiple plans to customers. (planA, planB, planC etc.) planA is lower than planB and planB is lower than planC. A customer can move from lower plan to higher plan but not vice-versa. If a customer is on planA and wants to 'activate' planB, then planA must be cancelled. Essentially, a plan can be 'activated' and 'deactivated'. I had 2 designs in mind.
interface Plan {
activate();
deactivate();
}
This interface will be inherited by each plans' (planA, planB, planC, etc). The activate method would be inherited and look something like this:
activate() {
Plan planToCancel = getLowerGradePlanToCancel()
planToCancel.cancel();
// perform business logic to activate plan.
}
Option B is something similar to strategy pattern: I have 2 interfaces:
interface Activate {
activate();
}
interface Deactivate {
deactivate()
}
Each of the plans will inherit those interfaces. Then my business logic would look something like this:
activatePlan(planName, planToDeactivate) {
Activate activate = Factory.getActivateInstanceForPlan(planName);
DeActivate dectivate = Factory.getActivateInstanceForPlan(planToDeactivate);
deactivate.deactivate();
activate.activate();
}
Of the two designs which one is more appropriate (Object Oriented) and why ? The only thing in code that is likely to change is more plans will be added in future.
You have 3 plans. Plan C can't go higher and similarly plan A can't go lower. Plan B can do both operations. Use one interface and put activate and deactivate methods there. You already mentioned that on option A. Use template pattern there to give an opportunity to change their behaviours for your plans. This will be appropriate if you will add another plans later on. This will help you a lot when you add another plans.
If you will have only three plans, then second option is more appropriate. Since you have only 3 plans and only one of them using activate and deactivate together, then you don't need to implement both of the methods, interfaces. This will decrease the dependencies of your code.
Pick the best choice for your case.
I have a different approach in mind where you have a class that manages all the plans, while plan interface is encapsulated and only reveals the necessary of its API.
I think this approach will have minimal code modification for each added Plan, moreover, it can prevent user from making mistakes (e.g. downgrading a plan).
The essential interfaces:
interface Plan {
public Plan next();
public boolean isActivated();
// for debug purposes
public String planDescription();
}
interface PlansManager {
public Plan nextPlan(Plan current);
}
The basic idea is to have some SemiConcretePlan class which implements the static (mutual) behaviour in all plans, the public API is next & isActivated while activate and cancel methods private (you don't want the user to cancel a plan without switching to the next or to activated a cancelled one be keeping a previous Plan pointer on it) and only the PlansManager or the Plan itself will handle the activation and cancellation, PlansManager activates the first plan and returns it and next method uses PlansManager to get the next and only the SemiConcertePlan activate the current and cancels the previous Plan.
Here the SemiConcertePlan:
abstract class SemiConcretePlan implements Plan {
private PlansManager m_plansManager;
private boolean m_isActivated;
private int m_id;
private static int s_idGenerator = 0, s_firstActivatedId = 1;
public SemiConcretePlan(PlansManager plansManager){
m_plansManager = plansManager;
m_id = generateId();
m_isActivated = (m_id == s_firstActivatedId);
}
private int generateId() {
return ++s_idGenerator;
}
private void activatePlan() {
this.m_isActivated = true;
}
private void cancelPlan() {
this.m_isActivated = false;
}
public boolean isActivated() {
return this.m_isActivated;
}
public Plan next() {
this.cancelPlan();
SemiConcretePlan nextPlan = (SemiConcretePlan) m_plansManager.nextPlan(this);
nextPlan.activatePlan();
return nextPlan;
}
public boolean equals(Object other) {
if (this == other)
return true;
if (other == null || !(other instanceof SemiConcretePlan) || this.hashCode() != other.hashCode())
return false;
SemiConcretePlan otherPlan = ((SemiConcretePlan) other);
if (m_id != ((SemiConcretePlan) otherPlan).m_id)
return false;
return true;
}
public abstract int hashCode();
public abstract String planDescription();
}
planDescription method is an example of dynamic method, hashCode is needed for class PlansManager to hash plans in map which map current plan to higher (next) plan.
Here is the AscedingPlansManager class:
class AscedingPlansManager implements PlansManager{
private List<Plan> m_plansList;
private Map<Plan, Plan> m_planToHigherPlanMapping;
public AscedingPlansManager() {
m_plansList = new LinkedList();
m_planToHigherPlanMapping = new HashMap();
Plan[] plans = {
new PlanA(this),
new PlanB(this),
new PlanC(this),
new PlanD(this)
};
for(int i = 0; i < plans.length - 1; ++i) {
m_plansList.add(plans[i]);
m_planToHigherPlanMapping.put(plans[i], plans[i+1]);
}
m_plansList.add(plans[plans.length - 1]);
m_planToHigherPlanMapping.put(plans[plans.length - 1], plans[plans.length - 1]);
}
public Plan nextPlan(Plan current) {
return m_planToHigherPlanMapping.getOrDefault(current, null);
}
private void activatePlan(Plan plan) {
try {
Method privateActivateMethod = SemiConcretePlan.class.getDeclaredMethod("activatePlan");
privateActivateMethod.setAccessible(true);
privateActivateMethod.invoke(plan);
} catch(Exception e) {
e.printStackTrace();
}
}
public void cancelAll() {
for(Plan plan: m_plansList)
try {
Method privateActivateMethod = SemiConcretePlan.class.getDeclaredMethod("cancelPlan");
privateActivateMethod.setAccessible(true);
privateActivateMethod.invoke(plan);
} catch(Exception e) {
e.printStackTrace();
}
}
public Plan firstPlan() {
Plan first = m_plansList.get(0);
this.activatePlan(first);
return first;
}
public boolean[] plansToActivationState() {
boolean[] ret = new boolean[m_plansList.size()];
int index = 0;
for(Plan plan: m_plansList)
ret[index++] = plan.isActivated();
return ret;
}
}
I know that this is huge code, but I think it will make add plans easy, you will only need to change the hashCode method, the sequence of the plans can be changed in the constructor of AscedingPlansManager or creating a different manger class from scratch.
Here is the full code, you can see how little changes I needed to do for class PlanD:
import java.util.;
import java.lang.reflect.;
interface Plan {
public Plan next();
public boolean isActivated();
// for debug purposes
public String planDescription();
}
interface PlansManager {
public Plan nextPlan(Plan current);
}
abstract class SemiConcretePlan implements Plan {
private PlansManager m_plansManager;
private boolean m_isActivated;
private int m_id;
private static int s_idGenerator = 0, s_firstActivatedId = 1;
public SemiConcretePlan(PlansManager plansManager){
m_plansManager = plansManager;
m_id = generateId();
m_isActivated = (m_id == s_firstActivatedId);
}
private int generateId() {
return ++s_idGenerator;
}
private void activatePlan() {
this.m_isActivated = true;
}
private void cancelPlan() {
this.m_isActivated = false;
}
public boolean isActivated() {
return this.m_isActivated;
}
public Plan next() {
this.cancelPlan();
SemiConcretePlan nextPlan = (SemiConcretePlan) m_plansManager.nextPlan(this);
nextPlan.activatePlan();
return nextPlan;
}
public boolean equals(Object other) {
if (this == other)
return true;
if (other == null || !(other instanceof SemiConcretePlan) || this.hashCode() != other.hashCode())
return false;
SemiConcretePlan otherPlan = ((SemiConcretePlan) other);
if (m_id != ((SemiConcretePlan) otherPlan).m_id)
return false;
return true;
}
public abstract int hashCode();
public abstract String planDescription();
}
class AscedingPlansManager implements PlansManager{
private List<Plan> m_plansList;
private Map<Plan, Plan> m_planToHigherPlanMapping;
public AscedingPlansManager() {
m_plansList = new LinkedList();
m_planToHigherPlanMapping = new HashMap();
Plan[] plans = {
new PlanA(this),
new PlanB(this),
new PlanC(this),
new PlanD(this)
};
for(int i = 0; i < plans.length - 1; ++i) {
m_plansList.add(plans[i]);
m_planToHigherPlanMapping.put(plans[i], plans[i+1]);
}
m_plansList.add(plans[plans.length - 1]);
m_planToHigherPlanMapping.put(plans[plans.length - 1], plans[plans.length - 1]);
}
public Plan nextPlan(Plan current) {
return m_planToHigherPlanMapping.getOrDefault(current, null);
}
private void activatePlan(Plan plan) {
try {
Method privateActivateMethod = SemiConcretePlan.class.getDeclaredMethod("activatePlan");
privateActivateMethod.setAccessible(true);
privateActivateMethod.invoke(plan);
} catch(Exception e) {
e.printStackTrace();
}
}
public void cancelAll() {
for(Plan plan: m_plansList)
try {
Method privateActivateMethod = SemiConcretePlan.class.getDeclaredMethod("cancelPlan");
privateActivateMethod.setAccessible(true);
privateActivateMethod.invoke(plan);
} catch(Exception e) {
e.printStackTrace();
}
}
public Plan firstPlan() {
Plan first = m_plansList.get(0);
this.activatePlan(first);
return first;
}
public boolean[] plansToActivationState() {
boolean[] ret = new boolean[m_plansList.size()];
int index = 0;
for(Plan plan: m_plansList)
ret[index++] = plan.isActivated();
return ret;
}
}
class PlanA extends SemiConcretePlan {
public PlanA(PlansManager plansManager) {
super(plansManager);
}
public int hashCode() {
return 1;
}
public String planDescription() {
return "This is PlanA";
}
}
class PlanB extends SemiConcretePlan {
public PlanB(PlansManager plansManager) {
super(plansManager);
}
public int hashCode() {
return 2;
}
public String planDescription() {
return "This is PlanB";
}
}
class PlanC extends SemiConcretePlan {
public PlanC(PlansManager plansManager) {
super(plansManager);
}
public int hashCode() {
return 3;
}
public String planDescription() {
return "This is PlanC";
}
}
class PlanD extends SemiConcretePlan {
public PlanD(PlansManager plansManager) {
super(plansManager);
}
public int hashCode() {
return 4;
}
public String planDescription() {
return "This is PlanD";
}
}
public class Main{
public static void main(String []args){
AscedingPlansManager ascedingPlansManager = new AscedingPlansManager();
Plan currentPlan = ascedingPlansManager.firstPlan();
int i = 0, maxIterations = 5;
while((++i) <= maxIterations) {
System.out.println(currentPlan.planDescription());
System.out.println(Arrays.toString(ascedingPlansManager.plansToActivationState()));
currentPlan = currentPlan.next();
}
ascedingPlansManager.cancelAll();
System.out.println("After canceling all plans");
System.out.println(Arrays.toString(ascedingPlansManager.plansToActivationState()));
}
}
I still not sure of my implementation, I usually access private method in c++ with friend modifier, if you want to discuss anything feel free to do so.
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
I have worked on this the whole day and cannot think of a good solution. I am to implement a breadth first search algorithm in order to solve a sliding puzzle. Here are the relevant parts of my code so far. (I have yet to test if it works since it is incomplete)
So far, this code is expected to traverse through all the possibilities and arrive at the goal. However, I cannot think of a way to record that path from initial to goal state.
private void addToQueue(PuzzleState nextPS) {
if (notVisitedAndNotNull(nextPS))
queue.add(nextPS);
}
private void solveByBFS() {
queue.clear();
queue.add(this.initialState);
long startTime = System.currentTimeMillis();
while(!queue.isEmpty()) { //TODO create a way to backtrack and get a path
if (queue.size() > maxQueueSize)
maxQueueSize = queue.size();
this.currentState = queue.poll();
if (this.currentState.equals(finalState)) { //TODO check if cannot progress any further and terminate
System.out.println("Successful! Ending Time: " + startTime);
return;
}
visited.add(this.currentState);
this.addToQueue(this.currentState.moveUp());
this.addToQueue(this.currentState.moveDown());
this.addToQueue(this.currentState.moveRight());
this.addToQueue(this.currentState.moveLeft());
}
return;
}
So I want a way to back track and get from the goal node to the initial state, reverse the path, and then print it out in a list.
Here is the data structure I am using:
public class SimplePuzzleState implements PuzzleState{
private int rowSz;
private int sz;
private int zeroPos;
private int[] gameState;
#Override
public void configureState(int[] gameState) {
rowSz = (int) Math.sqrt(gameState.length);
sz = gameState.length;
zeroPos = PuzzlePropertyUtility.findZeroPosition(gameState);
this.gameState = gameState;
}
#Override
public PuzzleState moveUp() {
if (zeroPos <= rowSz - 1) {
return null;
}
this.swap(zeroPos, zeroPos - rowSz);
return this.createNewUpdatedState();
}
#Override
public PuzzleState moveDown() {
if (zeroPos >= sz - rowSz) {
return null;
}
this.swap(zeroPos, zeroPos + rowSz);
return this.createNewUpdatedState();
}
#Override
public PuzzleState moveLeft() {
if (zeroPos % rowSz <= 0) {
return null;
}
this.swap(zeroPos, zeroPos - 1);
return this.createNewUpdatedState();
}
#Override
public PuzzleState moveRight() {
if (zeroPos % rowSz >= rowSz -1) {
return null;
}
this.swap(zeroPos, zeroPos + 1);
return this.createNewUpdatedState();
}
#Override
public boolean isEqual(PuzzleState other) {
if (other != null) {
if (this.getStateArray() instanceof int[] && other.getStateArray() instanceof int[])
return (Arrays.equals(this.getStateArray(), other.getStateArray()));
}
return false;
}
#Override
public int[] getStateArray() {
return gameState;
}
private void swap(int pos1, int pos2) {
int temp = this.gameState[pos1];
this.gameState[pos1] = this.gameState[pos2];
this.gameState[pos2] = temp;
}
private PuzzleState createNewUpdatedState() {
PuzzleState newState = new SimplePuzzleState();
newState.configureState(this.getStateArray());
return newState;
}
}
Here is the PuzzleState Interface:
public interface PuzzleState {
public void configureState(int[] gameState);
PuzzleState moveUp();
PuzzleState moveDown();
PuzzleState moveLeft();
PuzzleState moveRight();
boolean isEqual(PuzzleState other);
int[] getStateArray();
}
I have thought about adding an attribute to SimplePuzzleState to include a parent node.
However, I cannot modify the interface which it implements since my instructor does not allow that. Therefore, I cannot backtrack using a linked list method. Are there any smart ways to record the correct path? In the end, my instructor wants me to print a list containing enums which represent the movements. So I have to figure how to map the enums to functions moveUp, moveDown etc.
Thank you in advance. I apologize for posting so much code, but I really need advice on which direction I should take.
You have the right idea. If you can't add parent pointers to the states, then just maintain a HashMap with the same information called something like previous. When you create the four
child states, add mappings from the parent to these four.
// A map to hold parent relations.
HashMap<SimplePuzzleState, SimplePuzzleState> previous = new HashMap<>();
...
// Now change the add function.
private void addToQueue(PuzzleState parentPS, PuzzleState nextPS) {
if (notVisitedAndNotNull(nextPS)) {
queue.add(nextPS);
previous.add(nextPS, parentPS);
nextPS.updateParent(this); // and update where we got from
}
}
// Then update the calls to match:
this.addToQueue(currentState, this.currentState.moveUp());
...
When you find the goal, trace back to the start using the hash just as you would the parent pointers.
if (this.currentState.equals(finalState)) {
System.out.println("Successful! Ending Time: " + startTime);
System.out.println("Path back to start:");
PuzzleState state = currentState;
do {
state.print();
state = previous.get(state);
} while (state != null);
}
Add to SimplePuzzleState another field called gotHereFrom and when you call addToQueue() update this field (per each item). When you're done, instead if printing "successful" and return; start iterating back according to gotHereFrom and print the nodes all the way back:
public class SimplePuzzleState implements PuzzleState{
private int rowSz;
private int sz;
private int zeroPos;
private int[] gameState;
private SimplePuzzleState gotHereFrom; // add this guy
...
protected void updateParent(SimplePuzzleState gotHereFrom) {
this.gotHereFrom = gotHereFrom;
}
...
}
and:
private void addToQueue(PuzzleState nextPS) {
if (notVisitedAndNotNull(nextPS)) {
queue.add(nextPS);
nextPS.updateParent(this); // and update where we got from
}
}
iterating the results:
...
if (this.currentState.equals(finalState)) { //TODO check if cannot progress any further and terminate
System.out.println("Successful! Ending Time: " + startTime);
String path = "";
while (gotHereFrom != null) {
path += " -> " + gotHereFrom;
gotHereFrom = gotHereFrom.getGotHereFrom();
}
System.out.println(path);
return;
}
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?
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;
}
}