I have a design and object structuring related question. Here is the problem statement:
I have a Robot object which is suppose to traverse the ground on its own. It would be provided movement instructions and it must parse accordingly. For example sample input would be:
a. RotateRight|Move|RotateLeft|Move|Move|Move
Where move is a unit movement on a grid.
I did a very basic design in java. (Complete Code Pasted below)
package com.roverboy.entity;
import com.roverboy.states.RotateLeftState;
import com.roverboy.states.RotateRightState;
import com.roverboy.states.State;
public class Rover {
private Coordinate roverCoordinate;
private State roverState;
private State rotateRight;
private State rotateLeft;
private State move;
public Rover() {
this(0, 0, Compass.NORTH);
}
public Rover(int xCoordinate, int yCoordinate, String direction) {
roverCoordinate = new Coordinate(xCoordinate, yCoordinate, direction);
rotateRight = new RotateRightState(this);
rotateLeft = new RotateLeftState(this);
move = new MoveState(this);
}
public State getRoverState() {
return roverState;
}
public void setRoverState(State roverState) {
this.roverState = roverState;
}
public Coordinate currentCoordinates() {
return roverCoordinate;
}
public void rotateRight() {
roverState = rotateRight;
roverState.action();
}
public void rotateLeft() {
roverState = rotateLeft;
roverState.action();
}
public void move() {
roverState = move;
roverState.action();
}
}
package com.roverboy.states;
public interface State {
public void action();
}
package com.roverboy.entity;
import com.roverboy.states.State;
public class MoveState implements State {
private Rover rover;
public MoveState(Rover rover) {
this.rover = rover;
}
public void action() {
rover.currentCoordinates().setXCoordinate(
(Compass.EAST).equalsIgnoreCase(rover.currentCoordinates()
.getFacingDirection()) ? rover.currentCoordinates()
.getXCoordinate() + 1 : rover.currentCoordinates()
.getXCoordinate());
rover.currentCoordinates().setXCoordinate(
(Compass.WEST).equalsIgnoreCase(rover.currentCoordinates()
.getFacingDirection()) ? rover.currentCoordinates()
.getXCoordinate() - 1 : rover.currentCoordinates()
.getXCoordinate());
rover.currentCoordinates().setYCoordinate(
(Compass.NORTH).equalsIgnoreCase(rover.currentCoordinates()
.getFacingDirection()) ? rover.currentCoordinates()
.getYCoordinate() + 1 : rover.currentCoordinates()
.getYCoordinate());
rover.currentCoordinates().setYCoordinate(
(Compass.SOUTH).equalsIgnoreCase(rover.currentCoordinates()
.getFacingDirection()) ? rover.currentCoordinates()
.getYCoordinate() - 1 : rover.currentCoordinates()
.getYCoordinate());
}
}
package com.roverboy.states;
import com.roverboy.entity.Rover;
public class RotateRightState implements State {
private Rover rover;
public RotateRightState(Rover rover) {
this.rover = rover;
}
public void action() {
rover.currentCoordinates().directionOnRight();
}
}
package com.roverboy.states;
import com.roverboy.entity.Rover;
public class RotateLeftState implements State {
private Rover rover;
public RotateLeftState(Rover rover)
{
this.rover = rover;
}
public void action() {
rover.currentCoordinates().directionOnLeft();
}
}
package com.roverboy.entity;
public class Coordinate {
private int xCoordinate;
private int yCoordinate;
private Direction direction;
{
Direction north = new Direction(Compass.NORTH);
Direction south = new Direction(Compass.SOUTH);
Direction east = new Direction(Compass.EAST);
Direction west = new Direction(Compass.WEST);
north.directionOnRight = east;
north.directionOnLeft = west;
east.directionOnRight = north;
east.directionOnLeft = south;
south.directionOnRight = west;
south.directionOnLeft = east;
west.directionOnRight = south;
west.directionOnLeft = north;
direction = north;
}
public Coordinate(int xCoordinate, int yCoordinate, String direction) {
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
this.direction.face(direction);
}
public int getXCoordinate() {
return xCoordinate;
}
public void setXCoordinate(int coordinate) {
xCoordinate = coordinate;
}
public int getYCoordinate() {
return yCoordinate;
}
public void setYCoordinate(int coordinate) {
yCoordinate = coordinate;
}
public void directionOnRight()
{
direction.directionOnRight();
}
public void directionOnLeft()
{
direction.directionOnLeft();
}
public String getFacingDirection()
{
return direction.directionValue;
}
}
class Direction
{
String directionValue;
Direction directionOnRight;
Direction directionOnLeft;
Direction(String directionValue)
{
this.directionValue = directionValue;
}
void face(String directionValue)
{
for(int i=0;i<4;i++)
{
if(this.directionValue.equalsIgnoreCase(directionValue))
break;
else
directionOnRight();
}
}
void directionOnRight()
{
directionValue = directionOnRight.directionValue;
directionOnRight = directionOnRight.directionOnRight;
directionOnLeft = directionOnRight.directionOnLeft;
}
void directionOnLeft()
{
directionValue = directionOnLeft.directionValue;
directionOnRight = directionOnLeft.directionOnRight;
directionOnLeft = directionOnLeft.directionOnLeft;
}
}
Now my doubt is with this last class "Direction" and "Coordinate". coordinate represents a coordinate object for rover which helps it maintain its direction. Currently to keep track of direction I am using a doubly linked list of Direction objects, which pretty much work like a compass. Rotate left or right.
Here are the questions that I have.
1. I have used state pattern and shown design for direction tracking. Is there a better approach to simplify even this? Rem. I need to maintain coordinates correctly; such that if you move towards +y axis, my coordinates should be in + else in minus. Same for X axis.
Currently the responsibility for changing the face of the rover is indirectly delegated to coordinates and to direction class. Is this really correct? Isn't rover responsible for maintaining direction? Am I really right in my design to delegate that responsibility down to coordinate and direction class; just because it is easier to manipulate it there?
Any simple design improvements and suggestions on code will be most welcome. Feel free to critique.
Thanks for your patience and feedback; in advance.
Here's a Direction enum I came up with the other day, of which I am perhaps inordinately fond. Perhaps you will find it useful in your code.
import java.awt.Point;
public enum Direction {
E(1, 0), N(0, 1), W(-1, 0), S(0, -1);
private final int dy;
private final int dx;
private Direction(int dx, int dy) {
this.dx = dx;
this.dy = dy;
}
public Direction left() {
return skip(1);
}
public Direction right() {
return skip(3);
}
public Direction reverse() {
return skip(2);
}
private Direction skip(int n) {
final Direction[] values = values();
return values[(ordinal() + n) % values.length];
}
public Point advance(Point point) {
return new Point(point.x + dx, point.y + dy);
}
}
You're asking for how to simplify. If I may suggest something bold, why not use an opaque int for direction and have a static class to deal with it? By "opaque int" I mean that your code would never use it directly, but only as argument to the Direction class.
Here's some partial java-styled pseudocode to show what I mean.
// 0 = east, 1 = north, 2 = west, ...
public class Direction {
static int [] moveX = [ 1, 0, -1, 0];
static final int NORTH = 1;
// coordinates after moving one step in the given direction
static Pair move(int direction, Pair old) {
return new Pair( old.x + moveX[direction] , old.y + moveY[direction] );
}
static int turnLeft(int direction) {
return (direction+1) % 4;
}
static int turnRight(int direction) {
return (direction+3) % 4;
}
}
This way of doing things would have the advantage of using fewer allocations, so the garbage collector won't need to run as often. Another advantage is that the design remains object-oriented in the sense that you can easily change the direction class if later you want to be able to rotate by e.g. 45 degrees at a time.
To answer your other questions, I think it's perfectly fine to delegate to the Direction class the task of changing a coordinate along a certain direction. The rover would be responsible for maintaining direction only in the sense that the rover object would contain an int field to store the direction it's facing.
The first thing What comes to my mind when I see this code is that Direction should not have a String field directionValue, but rather a field storing a Compass (i.e. Compass.EAST, Compass.WEST). This would get you rid of the String comparisons in MoveState.action() and should therefore make your code considerably cleaner.
There also seems to be a problem with naming: maybe NORTH, EAST, WEST, and SOUTH should be in an enum called Direction (instead of Compass), and directionOnRight() etc. in the current Direction implementation should be its static methods (getting the current direction as a single argument, and returning the right/left/reverse direction)? You don't really need to store them in extra fields IMHO (remember the saying about premature optimization ;-).
My immediate thought upon looking at this is some confusion. The Rover class has 4 states and a direction, which seems a little counter intuitive. I would expect a position and a direction (for State I would, perhaps, expect, ON/OFF/RECHARGING or something similar).
So, I would investigate Java enums and have a NORTH/SOUTH/EAST/WEST Direction enum for the direction. The position (coordinate) has x/y positions, and to move, I would simply implement a deltaX() and deltaY() on the facing enumeration (it looks like Carl has just posted something similar)
Then your movement code would simply look like:
x += facing.deltaX()
y += facing.deltaY()
whichever direction you're facing. Note this doesn't delegate the movement. The Rover always moves, but the Direction enumeration gives it the dx/dy to change by.
The enumeration can also have methods clockwise() and counterClockwise(), so calling NORTH.clockwise() would return your new facing value EAST. Each enumeration instance would only have the delta and clockwise/counter-clockwise methods, and your Rover simply has the following:
private Direction facing;
private int x;
private int y;
which seems much more intuitive and what I'd expect. I've expressed x and y separately, but you may want to wrap in one class. If you do that, then the Direction enumeration should handle such an object, and not rely on it being broken apart again into x and y.
It seems too complicated for me. I think it should be done in such a way: let your robot know his turning angle. Then if he is asked to turn left or right he will just change this angle. When he is asked to move he will move according to this angle in x,y coordinates. angle can be stored like compass or even simplier with real angle (0, 90, 180, 270). It is easy to move robot in angle direction by multiplying movement step on sin(angle) and cos(angle). Why cant it be that simple? It will also handle more directions that just 4 and youll be able to move in any step range.
Related
I'm having trouble calling move.m_north from another function.
It is asking me to make the class move and the function m_north static, but if I do i can't reference y unless I make it static too.
I found that if y is static then any dot object I make will have the same value for y, and I need multiple dots
public class dot {
int y=0; //<-- 3. but if I make this static then it will stay the same for every object
public void step(int direction) {
switch (direction){
case 0:
move.m_north(); //<-- 1. is asking to make move.m_north static
}
}
public class move {
public int m_north() {
if (y > 0) {
y -= 1; //<-- 2. but I need to modify and read non static variables
return -1;
} else return -2;
}
}
}
I am able to call m_north if it is not in the move class but there are many similar functions which I believe need to be split up so I can use same names and it becomes easier to find different functions.
I would much appreciate any assistance.
You can make this work by declaring an instance of the move class. For example (with captialization changed to match Java naming conventions):
public class Dot {
int y=0;
Move move = new Move();
public void step(int direction) {
switch (direction){
case 0:
move.m_north();
}
}
public class Move {
public int m_north() {
if (y > 0) {
y -= 1;
return -1;
} else return -2;
}
}
}
Note that Move with an uppercase M is the class name, and move with a lowercase m is the name of an instance variable in the class Dot.
The reason this is required is that m_north requires an enclosing instance of Dot in order to access its y field. To put it another way, you need to call m_north on a specific dot's move instance. Making the method static doesn't provide an enclosing dot in scope.
Is there a way to create a listener (JavaFX) for any changes made to any of an object's field?
I have a coordinate object:
public class Coord {
public int x;
public int y;
public Coord(int aX, int aY) {
x = aX;
y = aY;
}
}
I have a component that creates a coordinate object when the mouse enters and destroys it when it exits. I've attached an invalidation listener:
this.setOnMouseEntered(event -> {
_hoverCoord = new SimpleObjectProperty<Coord>(getCoord(event.getX(), event.getY()));
_hoverCoord.addListener(redraw);
});
this.setOnMouseExited(event -> {
_hoverCoord = null;
});
When the mouse moves, I've been creating a new coordinate. Great, the invalidation fires because I'm replacing the coordinate. But this creates a whole bunch of these short-lived objects. I've resolved this by just calling the code I want directly in the mouse move, but it raised the following questions:
My first question is: Is that kind of rapid-fire object creation/destruction worth worrying about, generally? (I know that's a hard question to answer but I'm thinking in terms of garbage collection when creating tens of thousands of objects in a short time.)
My second question is: Is there a "listener" that just watches a POJO like Coord for field level changes?
My third question is: If not, is there a way to preserve Coord as a simple object and yet listen for specific field changes (without adding methods or changing the x and y from int)? I mean, no accessors for the fields.
My fourth question is: If not, how would I put in the accessors in Coord?
First, transform your Coord in a JavaFX Bean:
public class Coord{
private final IntegerProperty x = new SimpleIntegerProperty(this, "x");
private final IntegerProperty y = new SimpleIntegerProperty(this, "y");
public final void setX(int x){ this.x.set(x); }
public final int getX(){ return x.get(); }
public final IntegerProperty xProperty(){ return this.x; }
//Repeat for y.
}
Then, you may add an invalidation or change listener to the x property:
myCoordinate.xProperty().addListener(redraw);
myCoordinate.yProperty().addListener(redraw);
Now, there's a question: why do you need to listen the coordinates? If you need to compute something, you may use the helper Bindings, for instance, if you want to compute x*y each time the cursor moves, then you may use:
productProperty.bind(Bindings.createIntegerBinding(
()->coordinate.getX() * coordinate.getY(), //Compute x*y
coordinate.xProperty(), //dependency on x property
coordinate.yProperty()//dependency on y property
));
Or you may create your readonly property:
private final ReadOnlyIntegerWrapper product = new ReadOnlyIntegerWrapper(this, "product");
public Coord(){
init();
}
private void init(){
product.bind(Bindings.createIntegerBinding(
()->coordinate.getX() * coordinate.getY(), //Compute x*y
coordinate.xProperty(), //dependency on x property
coordinate.yProperty()//dependency on y property
));
}
public final int getProduct(){
return product.get();
}
public final ReadOnlyIntegerProperty productProperty(){
return product.getReadOnlyProperty();
}
I've seen many code-parts in mostly old(java mostly) projects that look like
if(type == typeOne){
callFunctionOne();
}else if (type == typeTwo){
callFunctionTwo();
}else if (type == typeThree){
callFunctionThree();
}//i've seen over ~800 lines like this!
where "type" could be an enum or really anything and the whole thing could be written in switch/case style too.
My question is: is there a "better"(more stylish/shorter/more readable) way to achieve this?
I've seen constructs in PHP like:
//where $type = "one","two" etc.
$functionName = 'callFunction' . $type;
new $functionName();
But im not sure if this is realy the "better" way and if its even possible in other Languages.
The more interesting question imo is what exactly you want to achieve by this?
Java is an object-oriented language. Therefore i would solve this by one subclass per type:
abstract class Type{
abstract void method();
}
class Type1 extends Type{
void method(){
//do sth. specific for this type
}
}
If the methods are actually all in the same class you could still call them out of these classes by simply passing yourself (i see that this could get ugly).
class RandomClass(){
void method1(){
//do sth for type1
}
void method2(){
//do sth for type2
}
}
abstract class Type{
RandomClass randomClass;
Type(RandomClass randomClass){
this.randomClass = randomClass;
}
abstract void method();
}
class Type1 extends Type{
void method(){
randomClass.method1();
}
}
class Type2 extends Type{
void method(){
randomClass.method2();
}
}
Otherwise you could use reflection, like suggested by Sohaib (example taken from his suggested link):
Yyyy.class.getMethod("methodName").invoke(someArgs)
But using Reflection for somehting like this seems very unhandy as it is inperformant and a nice trap for later maintenance (just imagine someone starts renaming the methods).
So to answer the question itself (at least how i understand it):
Dynamically calling methods e.g. by determining their name dynamically at runtime, is something you only do in scripting languages.
The object-oriented approach might come with overhead, but at the end is the better style for this kind of language.
If both solutions do not work for you, a switch statement or if-else cascade is your best alternative.
As noted in a comment, there are ways to use java's reflection capabilities. See this question for how to do that. That said, reflection is pretty bad style in java and should only be used if you really have no other option. Java's really big on OO-style programming and static type checking and using reflection is skimping on both of those focuses. In doing so you'll likely make your code just as complicated and way harder to debug.
Without reflection, there's not much better you can do if the code block in question happens exactly once. You'd have to implement the logic somewhere, probably involving the same if-else/switch block. However, if you find yourself copy-pasting that same if-elseif-elseif-elseif.... block in multiple places, you can do a bit better.
If type is an enum, you can move the logic to the enum itself, which is really nice from an OO standpoint. Consider the following:
public enum Direction {
NORTH,
SOUTH,
EAST,
WEST
}
public class Foo {
public void bar(Direction d) {
//At some point we want some logic to depend on the vector dx,dy form of d
int dx = 0;
int dy = 0;
switch(d) {
case NORTH:
dy = -1;
break;
case SOUTH:
dy = 1;
break;
case EAST:
dx = 1;
break;
case WEST:
dx = -1;
break;
}
//Use the values in dx, dy
}
}
It's clearly a bad idea to copy-paste this block around your project. If you ever add a new direction, you'd have to return to every such block to add the correct addition. From an OO standpoint, the dx, dy fields are truly part of the enum value, and should be a part of it to begin with. Thus we can change the above to the following:
public enum Direction {
NORTH,
SOUTH,
EAST,
WEST;
public int getDX() {
switch(this) {
case WEST: return -1;
case EAST: return 1;
default: return 0;
}
}
public int getDY() {
switch(this) {
case NORTH: return -1;
case SOUTH: return 1;
default: return 0;
}
}
}
Or, (IMO) even better, represent them as a field
public enum Direction {
NORTH(0,-1),
SOUTH(0,1),
EAST(1,0),
WEST(-1,0);
private int dx;
private int dy;
private Direction(int dx, int dy) {
this.dx = dx;
this.dy = dy;
}
public int getDX() {
return dx;
}
public int getDY() {
return dy;
}
}
From there we can simply use these methods directly in Foo.bar() and don't need any logic:
public class Foo {
public void bar(Direction d) {
//can directly use d.getDX() and d.getDY()
}
}
Your question about function calling is the same, if one level removed. We can either add the switch straight to the enum:
public enum Type {
VALUE_ONE, VALUE_TWO, ...
public void callFunc() {
switch(this) {
case VALUE_ONE:
callFunctionOne();
return;
case VALUE_TWO:
callFunctionTwo();
return;
//....
}
}
}
And then just use it by directly referencing that function:
Type t = //....
t.callFunc();
You could even use some java-8 stuff to represent the function-to-call as a field
#FunctionalInterface
public interface Unit {
public void apply();
}
public enum Type {
VALUE_ONE(Foo::baz),
VALUE_TWO(Foo::baz2),
//...
private Unit funcToCall;
private Type(Unit u) {
this.funcToCall = u;
}
public void callFunc() {
funcToCall.apply();
}
}
If type is not an enum, you can use some (but not all) of the above options. You can still lump your switch logic into a helper method/class and pass control over to it instead of copy/pasting. The more that type is supposed to represent something, and the more you find yourself wanting to switch over it, the more likely an enum is the correct choice.
I have a player which can feed a dog or chop a tree.
Below are the classes I have written:
public class Dog {
private int health;
public void feed(Food food){
health = health + food.getNutritionalValue();
}
}
public class Player{
public void feed(Dog dog, Food food) {
dog.feed(food);
}
Player and Dog both have methods that are "active".
Player feeds the dog and dog starts eating the food (I am not really sure if it is good to couple methods in this way).
On the other hand, I have tree. And player is able to chop the tree.
public class Player{
public void chop(Tree tree) {
//At this point I am not sure
}
I am not sure if I would use getters and setters of Tree class to interact with the Tree.
Or if I should write an own method for this because the tree gets chopped so it is nothing really active I would call.
So, in the end, there would be two or more kinds of implementations but the two I am thinking of are:
tree.setAmountofWood = x
or
tree.gettingChopped(Damage int)
I think I should make an own method for this chopping-process.
Or is there any design principle I should follow?
I see 3 principles here,
SRP - It is the responsibility of the Tree to get chopped and fall down, but to cut is the responsibility of the Person!
Demeter's law - looks good from my POV.
OCP - The tree must be able to do further actions when get cut.
So you must use
tree.gettingChopped(Damage damage)
To your code:
The method Dog.feed is wrong, rename it to Dog.eat because the Dog is not feeding, the dog is eating. By the way, the food must reduce its NutritionalValue.
The health is an integer value, this is bad because in reality there is nothing like a numeral health. We may have a handicapped numeral value in percent, but this is more a byte who not can be in negative value. You should create a custom class for the Health! This way your code is open(OCP) for extensions like to be toxified or depresive.
I would start from something like this.
Tree can grow and receive damage.
public class Tree {
private int lumber;
public Tree(int size) {
this.lumber = size;
}
public void grow() {
this.lumber++;
}
public void grow(int size) {
this.lumber += size;
}
public int receiveDamage(int damage) {
int lumber = 0;
if (damage > this.lumber) {
lumber = this.lumber;
this.lumber = 0;
} else {
lumber = damage;
this.lumber -= damage;
}
return lumber;
}
}
Food just stores nutritional value.
public class Food {
private int nutrition;
public Food(int nutrition) {
this.nutrition = nutrition;
}
public int getNutritionalValue() {
return this.nutrition;
}
}
I'm not sure if all types of player can chop trees, so I created a class to separate responsibilities. You can move methods to the Player class if you like.
public class Woodcutter extends Player {
public int chop(Tree tree) {
// lumber amount may depend on a tool,
// i.e. axe, chainsaw, etc.
return tree.receiveDamage(10);
}
// fell down the tree
public int fell(Tree tree) {
int result = 0;
int lumber = 0;
do {
lumber = chop(tree);
result += lumber;
} while (lumber > 0);
return result;
}
}
Somewhere in your code
// create a tree and let it grow for a while
Tree tree = new Tree(10);
tree.grow(90);
// Start chopping
Woodcutter woodcutter = new Woodcutter();
System.out.println("Lumber received: " + woodcutter.chop(tree));
System.out.println("Lumber received: " + woodcutter.fell(tree));
Dog dog = new Dog();
Food food = new Food(5);
woodcutter.feed(dog, food);
I wouldn't dive into passive/active methods here. An 'active tree' may indeed be a misnomer.
I would rather consider calling an object's method as passing a message to the object. And you apparently need to send the message to the tree that it is currently being cut by someone, and let the tree decide when to e.g. fall() or to bend(), or to shake().
The tree has some internal state (strength? thickness of its trunk? health?). 'Sending a message' to the tree means to call its method, e.g. beingCut(), which in turn deteriorates the state of the tree. After the state of the tree reaches a certain limit, other actions (=consequences of tree's bad state) may be started by the tree.
Of course, as in every iteration of your main loop you tree has also the chance to get the message to grow(), so its state may improve a little each time, so eventually it may even recover from being only partially cut and reach its initial, perfect state back.
So, yes, while trees seem rather passive, they still react to messages/stimulus. :-)
I am programming a probe that moves through a 2D board in Java. To do this, I have two ArrayLists of Integer that contain the path that the probe has followed. The first ArrayList contains the x-coordinate, and the second one, the y-coordinate. What I would like to do is check whether the next tile of the movement has been visited or not, this is, whether the new x-coord and the new y-coord are in the corresponding ArrayList and share the same position.That way, if the new tile has been visited, I wouldn't move there. How could I possibly do this? I have tried with indexOf and lastIndexOf, but it doesn't work as each coordinate can be repeated an indefinite number of times. I also tried .contains but it didn't work either as I need that it is contained in both arrays in a specific position.
Any help would be appreciated.
First of all Java is object oriented so you should use objects. Why are you storing a coordinate in two separate arrays?
You can define your own type:
class Position implements Comparable<Position> {
public final int x;
public final int y;
Position(int x, int y) { this.x = x; this.y; }
#Override public int compareTo(Position other) { ... }
#Override public boolean equals(Object other) { ... }
#Override public int hashCode() { ... }
}
Then with this you can do whatever you want, for example
Set<Position> visited = new HashSet<Position>();
Map<Position, Integer> visitedWithSpecificPositionInPath = new HashMap<Position, Integer();
and so on.
A pretty messy approach would be to find all indexes of matching x-coordinates and for each index found check whether the y-coordinate for the given index is equal to the y in question.
So given coordinates x, y and array lists visitedX and visitedY you could do something like this:
public static boolean isVisited(int x, int y){
for(int i = 0; i < visitedX.size(), i++){
if(visitedX.get(i) == x){
if(visitedY.get(i) == y){
return true;
}
}
}
return false;
}
But as Jack has mentioned you should reconsider your data structure as looping over the complete x-coordinates list is not very efficient (though you could reduce limits of outer for loop with usage of visitedX.indexOf(x) and visitedX.lastIndexOf(x) ).