I am translating a solution to the Mars Rover problem written in Java. I am not sure how to deal with the Direction enum class found here.
I don't think I can do it like that in C#, therefore I would like to ask if anyone could suggest how to do this.
I was thinking of making an IDirection interface and a class for each Direction that inherits from that interface.
You could use a struct for this purpose, with a selected set of global singletons representing standard directions. I suggest a struct since your Direction object has value semantics:
public struct Direction : IEquatable<Direction>
{
short xstep;
short ystep;
public static Direction N { get { return new Direction(0, 1); } }
public static Direction E { get { return new Direction(1, 0); } }
public static Direction S { get { return new Direction(0, -1); } }
public static Direction W { get { return new Direction(-1, 0); } }
public static IEnumerable<Direction> Directions
{
get
{
yield return N;
yield return E;
yield return S;
yield return W;
}
}
Direction(int x, int y)
{
this.xstep = checked((short)x);
this.ystep = checked((short)y);
}
public int XStep { get { return xstep; } }
public int YStep { get { return ystep; } }
public Direction Left { get { return new Direction(-YStep, XStep); } }
public Direction Right { get { return new Direction(YStep, -XStep); } }
public override bool Equals(object obj)
{
if (obj is Direction)
{
var other = (Direction)obj;
return xstep == other.XStep && ystep == other.YStep;
}
return false;
}
public override int GetHashCode()
{
return (XStep.GetHashCode() | (YStep << 16).GetHashCode());
}
#region IEquatable<Direction> Members
public bool Equals(Direction other)
{
return this.xstep == other.xstep && this.ystep == other.ystep;
}
#endregion
public static Direction operator -(Direction direction)
{
return new Direction(-direction.XStep, -direction.YStep);
}
public static bool operator ==(Direction first, Direction second)
{
return first.Equals(second);
}
public static bool operator !=(Direction first, Direction second)
{
return !(first == second);
}
public override string ToString()
{
if (this == Direction.N)
return "N";
if (this == Direction.E)
return "E";
if (this == Direction.S)
return "S";
if (this == Direction.W)
return "W";
return string.Format("({0},{1}}", XStep.ToString(NumberFormatInfo.InvariantInfo), YStep.ToString(NumberFormatInfo.InvariantInfo));
}
}
The public static bool operator ==(Direction first, Direction second) allows directions to be compared simply using the == operator. This also requires overriding Equals and GetHashCode().
In C# enums are simple wrapper types over a finite set of primitive types, and sadly extension methods are the only way to extend them.
In Java, they're classes which you can extend with their own methods.
All you need to do is emulate that behavior. A possible approach could be:
public sealed class Direction {
public static readonly Direction N = new Direction(0, 1);
public static readonly Direction S = new Direction(0, -1);
public static readonly Direction E = new Direction(1, 0);
public static readonly Direction W = new Direction(-1, 0);
static Direction() {
N.Left = W;
N.Right = E;
S.Left = E;
S.Right = W;
E.Left = N;
E.Right = S;
W.Left = S;
W.Right = N;
}
private Direction(int stepSizeOnXAxis, int stepSizeOnYAxis)
{
StepSizeForXAxis = stepSizeOnXAxis;
StepSizeForYAxis = stepSizeOnYAxis;
}
public Direction Right { get; private set; }
public Direction Left { get; private set; }
public int StepSizeForXAxis { get; }
public int StepSizeForYAxis { get; }
}
Despite the fact that java seems to have this feature which C# doesn't, the reality is (as always) that C# is a much more modern language, and it requires much less code to produce the same results.
Your 72 lines of java code can be translated into these 35 lines of C#:
public class Direction
{
public static readonly Direction N = new Direction(0, 1);
public static readonly Direction S = new Direction(0, -1);
public static readonly Direction E = new Direction(1, 0);
public static readonly Direction W = new Direction(-1, 0);
private Direction(int stepSizeX, int stepSizeY)
{
this.StepSizeForXAxis = stepSizeX;
this.StepSizeForYAxis = stepSizeY;
}
static Direction()
{
N.Left = W;
N.Right = E;
S.Left = E;
S.Right = W;
E.Left = N;
E.Right = S;
W.Left = S;
W.Right = N;
}
public Direction Left { get; private set; }
public Direction Right { get; private set; }
public int StepSizeForXAxis { get; private set; }
public int StepSizeForYAxis { get; private set; }
}
This results in a class that can only be instantiated by itself (because of the private constructor), and has members that you can use in the same way you would use a C# enum, with the advantage of the additional properties:
var south = Direction.S;
var east = south.Left;
Console.WriteLine(east == south); // True
Console.WriteLine(south.StepSizeForXAxis); //0
Console.WriteLine(south.StepSizeForYAxis); //-1
java can be hardly compared to C# anymore, let alone claim any advantage over it, at least at the language level.
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.
public class GPSping {
private double pingLat;
private double pingLon;
private int pingTime;
}
The Trip class
public class Trip {
private ArrayList<GPSping> pingList;
public Trip() {
pingList = new ArrayList<>();
}
public Trip(ArrayList<GPSping> triplist) {
pingList = new ArrayList<>();
}
public ArrayList<GPSping> getPingList() {
return this.pingList;
}
public boolean addPing(GPSping p) {
int length = pingList.size();
int Time = pingList.get(length);
if (p.getTime() > this.pingList[length]) {
pinglist.add(p);
return True;
} else {
return False;
}
}
}
I am trying to add a GPS ping to this trip list but only if the time of p is after the last time in this trip list. I am very new to Java and am struggling with wrapping my head around the syntax some help would be greatly appreciated.
First element in List has index 0, to to get the last one:
int Time = pingList.get(length - 1);
But I think, it's better to store maxPingTime to check it before add new GPSping:
class Trip {
private final List<GPSping> pingList = new ArrayList<>();
private int maxPingTime = Integer.MIN_VALUE;
public List<GPSping> getPingList() {
return pingList.isEmpty() ? Collections.emptyList() : Collections.unmodifiableList(pingList);
}
public boolean addPing(GPSping p) {
if (p.getPingTime() <= maxPingTime)
return false;
pingList.add(p);
maxPingTime = p.getPingTime();
return true;
}
}
final class GPSping {
private final double pingLat;
private final double pingLon;
private final int pingTime;
public GPSping(double pingLat, double pingLon, int pingTime) {
this.pingLat = pingLat;
this.pingLon = pingLon;
this.pingTime = pingTime;
}
}
P.S. Pay attention on Encapsulation OOP principle: GPSping should be final and pingList should not be directly retrieved.
I'm learning the concept of neural networks. I decided to try making the neuron class by myself. What is the best way to implement different activation functions in my code? Now it uses only the binary step function.
It's my first try in coding neural networks so if you have any suggestions about my code, or it is completely dumb, please let me know.
Here is my code:
public class Neuron {
// properties
private ArrayList<Neuron> input;
private ArrayList<Float> weight;
private float pot, bias, sense, out;
private boolean checked;
// methods
public float fire(){
pot = 0f;
if (input != null) {
for (Neuron n : input){
if (!n.getChecked()){
pot += n.fire()*weight.get(input.indexOf(n));
} else {
pot += n.getOut()*weight.get(input.indexOf(n));
} // end of condition (checked)
} // end of loop (for input)
} // end of condition (input exists)
checked = true;
pot -= bias;
pot += sense;
out = actFunc(pot);
return out;
} // end of fire()
// getting properties
public float getPot(){return pot;}
public boolean getChecked(){return checked;}
public float getOut(){return out;}
// setting properties
public void stimulate(float f){sense = f;}
public void setBias(float b){bias = b;}
public void setChecked(boolean c){checked = c;}
public void setOut(float o){out = o;}
// connection
public void connect(Neuron n, float w){
input.add(n);
weight.add(w);
}
public void deconnect(Neuron n){
weight.remove(input.indexOf(n));
input.remove(n);
}
// activation function
private float actFunc(float x){
if (x < 0) {
return 0f;
} else {
return 1f;
}
}
// constructor
public Neuron(Neuron[] ns, float[] ws, float b, float o){
if (ns != null){
input = new ArrayList<Neuron>();
weight = new ArrayList<Float>();
for (Neuron n : ns) input.add(n);
for (int i = 0; i < ws.length; i++) weight.add(ws[i]);
} else {
input = null;
weight = null;
}
bias = b;
out = o;
}
public Neuron(Neuron[] ns){
if (ns != null){
input = new ArrayList<Neuron>();
weight = new ArrayList<Float>();
for (Neuron n : ns) input.add(n);
for (int i = 0; i < input.size(); i++) weight.add((float)Math.random()*2f-1f);
} else {
input = null;
weight = null;
}
bias = (float)Math.random();
out = (float)Math.random();
}
}
First, define interface of any activation function:
public interface ActivationFunction {
float get(float f);
}
Then write some implementations:
public class StepFunction implements ActivationFunction {
#Override
public float get() {return (x < 0) ? 0f : 1f;}
}
public class SigmoidFunction implements ActivationFunction {
#Override
public float get() {return StrictMath.tanh(h);}
}
Finally, set some implementation to your Neuron:
public class Neuron {
private final ActivationFunction actFunc;
// other fields...
public Neuron(ActivationFunction actFunc) {
this.actFunc = actFunc;
}
public float fire(){
// ...
out = actFunc.get(pot);
return out;
}
}
as following:
Neuron n = new Neuron(new SigmoidFunction());
Note, neural netoworks are using signal propagation through neurons, where weights are produced. Computing of weight depends also on first derivative of an activation function. Therefore, I would extend ActivationFunction by method, which will return first derivative at specified point x:
public interface ActivationFunction {
float get(float f);
float firstDerivative(float x);
}
So the implemenations will look like:
public class StepFunction implements ActivationFunction {
#Override
public float get(float x) {return (x < 0) ? 0f : 1f;}
#Override
public float firstDerivative(float x) {return 1;}
}
public class SigmoidFunction implements ActivationFunction {
#Override
public float get(float x) {return StrictMath.tanh(x);}
// derivative_of tanh(x) = (4*e^(2x))/(e^(2x) + 1)^2 == 1-tanh(x)^2
#Override
public float firstDerivative(float x) {return 1 - Math.pow(StrictMath.tanh(x), 2);}
}
Then, use actFunction.firstDerivative(x); in fire() method where weight is being computed.
I have two classes BouncingBall and another one called ElasticBall. Both classes extends BallImpl which implements an interface called Ball.
public interface Ball {
int DEFAULT_RADIUS = 50;
int radius();
Point center();
void update();
}
public class BouncingBall extends BallImpl {
public static final int MOVEMENT_SPEED = 12;
static final int DOWN = 1;
static final int UP = -1;
private int direction;
BouncingBall(int x, int y, int direction) {
super(x, y);
this.direction = direction;
}
#Override
public void update() {
direction = reverseDirectionIfNecessary();
y = move();
}
private int reverseDirectionIfNecessary() {
if (movingTooHigh() || movingTooLow()) {
return switchDirection();
}
return this.direction;
}
private boolean movingTooLow() {
return y + radius >= BallWorld.BOX_HEIGHT && movingDown();
}
private boolean movingTooHigh() {
return y - radius <= 0 && movingUp();
}
private int switchDirection() {
return movingDown() ? UP : DOWN;
}
private int move() {
return y + (MOVEMENT_SPEED * direction);
}
private boolean movingDown() {
return direction == DOWN;
}
private boolean movingUp() {
return direction == UP;
}
}
public class ElasticBall extends BallImpl {
public static final int GROWTH_RATE = 2;
static final int GROW = 1;
static final int SHRINK = -1;
private int growthDirection;
ElasticBall(int x, int y, int radius, int growthDirection) {
super(x, y, radius);
this.growthDirection = growthDirection;
}
#Override
public void update() {
growthDirection = reverseGrowthDirectionIfNecessary();
radius = next();
}
private int reverseGrowthDirectionIfNecessary() {
if (growingTooBig() || shrinkingTooSmall()) {
return switchDirection();
}
return this.growthDirection;
}
private boolean shrinkingTooSmall() {
return radius <= 0 && shrinking();
}
private boolean growingTooBig() {
return radius >= Ball.DEFAULT_RADIUS && growing();
}
private int switchDirection() {
return growing() ? SHRINK : GROW;
}
private int next() {
return radius + (GROWTH_RATE * growthDirection);
}
private boolean shrinking() {
return growthDirection == SHRINK;
}
private boolean growing() {
return growthDirection == GROW;
}
}
I need to create a BouncingElasticBall which combines the behavior of the BouncingBall and the ElasticBall classes. I have poor knowledge in OOP, and I know Java does not allow multiple inheritance, so how can I solve this problem?
Thanks in advance.
One way you could approach this is to not extend BallImpl, but make sort-of plugins. Like this:
public class BallImpl implements Ball {
List<BallBehavior> behaviors = ...
#Override
public void update() {
behaviors.forEach(behavior -> behavior.update(this));
}
...
}
public interface BallBehavior {
void update(BallImpl ballImpl);
}
And then, just write your elastic and bouncing logic as behaviors.
Once you diverge hierarchies there's no way to merge them in java.
It's a design matter: if you know that ElasticBall and BouncingBall may be combined together, you should create two interfaces Elastic and Bouncing, both extending interface Ball, with common methods valid for both.
Then the common method implementations may be set into a common abstract class, let's say AbstractBall. At this point you can finally detail your three implementations:
ElasticBall extends AbstractBall implements Elastic
BouncingBall extendis AbstractBall implements Bouncing
ElasticBouncingBall extends AbstractBall implements Elastic, Bouncing
In this way you'll be able to control what to do in each method, reuse code for common stuff (in the abstract class).
You can use interfaces that allows multiple inheritance. Make the interface for each ballElasticBall and BouncingBall and implement both of them in BouncingElasticBall.
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)