What I am doing is transposing a c# project to java for practice in writing custom classes.
Unfortunately I cant figure out what the person is doing with "this" keyword inside the constructor.
// C# Code - How is this written in Java?
public Player this[int x, int y]
{
get { return squares[x, y]; }
set { squares[x, y] = value; }
}
I have transposed a lot of the code and am kind of stuck on this. I cant seem to find any information on this particular instance in Java. does anyone have a good lead for me?
That's not in the constructor. That's the declaration of an indexer. The Java equivalent would be something like:
public Player getPlayer(int x, int y)
{
// Note: Java doesn't have "real" multidimensional arrays,
// only arrays of arrays.
return squares[x][y];
}
public Player setPlayer(int x, int y, Player player)
{
squares[x][y] = player;
}
This is Using Indexers (C#).
This blog has some ideas of how to port the C# indexer to java code.
Basically it can be realized in a java getter/setter:
public Player get(int x, int y) { return squares[x][y];}
public Player set(int x, int y, Player p) { squares[x][y] = p;}
That's not a constructor, that's an indexer. Basically, this definition allows you to do:
Player playerAtOrigin = myGameBoard[0, 0];
In Java, only arrays have an indexer (e.g. myArray[i]), you cannot define your own indexers. Most likely, you'll want to translated this into two methods getPlayerAt(int x, int y) and setPlayerAt(int x, int y, Player player).
Related
I am trying to create a 'Map' object.
This 'Map' object should hold 'Point'(int x, int y) objects - and every point has a color represents by a char (a letter).
Here is a picture for example
I mustn't add fields to 'Point'. I mustn't use Generic objects.
I am thinking of how to apply this 'Map' object:
I thought maybe it can have to fields:
private Point[] MapPoints;
private char[] PointsColors;
The "Point[] MapPoints" array will hold the points.
The "char[] PointsColors" will hold the colors respectively.
I didn't think it through, but I feel it's kind of clumsy and might be difficult for me later in the code.
I am in a very basic level of object oriented programming - so please consider it when you offer a solution - it should be basic and limited to what we've learned in class.
If you design a 2D array like char[][] pointsColors you won't need a Point class anymore..... then you can browse/iterate rows and cols to find/set colors in the map, this approach has a couple of positive things
you dont need to create a class point for that.
you can set/get color directly just by knowing the coordinate where it is located...
Example:
char[][] pointsColors = new char[2][2];
// set color at 0,0 to red
pointsColors[0][0] = 'r';
// set color at 1,1 to green
pointsColors[1][1] = 'g';
// get color at 0,1
char foo = pointsColors[0][1];
Let's avoid generic classes and plan on our on. From the requirements it is crystal clear that we are not allowed to add fields to Point besides x and y and Point has to have an x and y. So the color mustn't be part of point. A 2D array containing char items to represent the points is not an option either, because from a given value we will not be able to reverse-engineer the coordinates and it was clearly stated that Point will have an x and an y field. So this means that we have a Point class:
public class Point {
public int x;
public int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
Since map has to be an object which will hold points, let's define its class:
public class Map {
public Point[][] points;
public char[][] colors;
public getColorOfPoint(Point point) {
return colors[point.x, point.y];
}
public Map(Point[][] points, char[][] colors) {
this.points = points;
this.colors = colors;
}
}
You can use HashMap collection, where in you can use your point object as key and the char value(representing the color of point) as its value. This way you can keep track of your colors related with objects.
I'm trying to create a program that starts with a Piece class. For the purpose of the exercise every other class extends Piece. The other classes contain methods for moving the pieces, either one space or n spaces.
All of the pieces are stored in a 2D array which the use to move around.
My problem is that if i make an array of Pieces I cannot access the move methods as they are stored in the subclasses. I also can't just cast the object because i have 4 different types that the user can ask to move.
This is the code that adds a piece to the board
//adds a piece based on given type, but only if the space is clear (null)
public void addpiece(String type, String n, String c, int x, int y){
if(board[x][y] == null){
if(type == "FastFlexible"){
board[x][y] = new FastFlexiblePiece(n,c,x,y);
}
else if(type == "FastPiece"){
board[x][y] = new FastPiece(n,c,x,y);
}
else if(type == "SlowFlexible"){
board[x][y] = new SlowFlexiblePiece(n,c,x,y);
}
else if(type == "SlowPiece"){
board[x][y] = new SlowPiece(n,c,x,y);
}
else{
System.out.println("Invaild type");
}
}
}
And this is the code that tries to move the piece, the error I get is because the parent Piece doesn't have a move method, but I can't figure out a way to get the pieces to cast correctly
//Move a piece, two method one for fast and one for slow
public void movePiece(int x, int y, String direction){
if(board[x][y] != null){
if(board[x][y].getType().equals("SlowPiece")){
board[x][y] = board[x][y].move(direction);
}
else if(board[x][y].getType().equals("SlowFlexible")){
board[x][y] = board[x][y].move(direction);
}
}
}
There is another similar method for fast pieces.
Constructor for the slowPiece:
//Constructor
public SlowPiece(String n, String c, int x, int y){
super(n,c,x,y);
this.setType("SlowPiece");
}
But the code doesn't notice what type any of the Pieces are and so I can't cast them correctly
The very aim of Polymorphism is to avoid writing code like the implementation specified for public void movePiece(int x, int y, String direction){.
board[x][y] can refer to SuperType Piece and any of its SubTypes like the SlowPiece, SlowFlexible, FastPiece, FastFlexible. Piece can have the abstract move behavior specified in the definition of the class, without having to provide the implementation. All the SubTypes of Piece class provide their own implementation for move method.
The method public void movePiece(int x, int y, String direction) would simply boil down to this :
public void movePiece(int x, int y, String direction){
board[x][y].move(direction);
}
At runtime, move method is dynamically dispatched depending upon the SubType of Piece class.
My suggestion is to add an abstract method to the parent Piece class.
public class Piece{
public abstract void move();
}
NOTE: now you can't directly instantiate a Piece. This code is illegal:
Piece p = new Piece();
Consider this:
public class Test {
public static int numberOfInstances = 0;
public int myInstanceID;
public String myInstanceName;
The static variable doesn't need to be called within an instance, it's available everywhere like this:
Test.numberOfInstances
When creating an instance, I only do this into my constructor:
public Test(int id, String name) {
myInstanceID = id;
myInstanceName = name;
numberOfInstances += 1;
}
I've recently discovered the this keyword and have noted some of its uses:
public Test() {
this(numberOfInstances + 1, "newInstance");
numberOfInstances += 1;
}
From what I've noticed, the this keyword allows you to call another one of the class' constructors. It also allows you to do this:
public Test(int x, int y) {
this.x = x;
this.y = y;
}
With java, I highly disagree with this style; same variable names, and I don't see the point of using this, especially after looking at the docs example. I look at this:
public Test(int a, int b) {
x = a;
y = b;
However, the use of the this keyword isn't necessary; In my code, I have a variables in my class (e.g. xCoordinate) where I don't use the this keyword (it's not static).
What I've been struggling to understand is what the difference is between non-static variables and this variables. Is there a difference? In one of my classes (the Paddle for Pong), I have this:
public class Pong {
public int xCoordinate;
public int yCoordinate;
and so on...
I never use the this keyword anywhere, and the data is stored within it's own instance.
Bottom line, my question is what is the difference between non-static variables and this.variables. Is it a standard coding practice? Why would I ever you the this keyword on non-static variables?
I think you may have almost answered your own question. You provided the function
public Test(int x, int y) {
this.x = x;
this.y = y;
}
However, what do you think would happen if you wrote it this way instead?
public Test(int x, int y) {
x = x;
y = y;
}
Noticed that I removed the this in the second function. Therefore, x and y would just be referring to the local x and y variables. this allows you to specify that you actually want to use the non-static class variables x and y.
If, as is typical, the parameter variable names of a constructor (say x) are the same as fields of the class, then the field names are shadowed by the parameters passed.
this is used in this case to disambiguate: this.x denotes the field x. It makes perfect sense. this means "reference to the current instance".
So, statements like this.x = x; are quite common.
If you still continue to dislike the Java style, and you adopt m_x-style notation for class fields, then you can write m_x = x; in your constructor. As you rightly point out, this is then not required.
this is also used as the notation for delegating constructors, as you point out.
The "this" keyword allows you to difference between method and instance variables:
public class Point {
private int x;
private int y;
public void add(int x, int y) {
this.x += x;
this.y += y;
}
}
There is no this variables. It's just used to tell the compiler that the variable you want to change is the declared field and not the local variable, in case they have the same name.
For the constructor part, this is just a shortcut for classes which have multiple constructors. You can write the code once and just call that from the alternative constructors.
There is also a similiarly used keyword super, which allows you to call methods and constructors of the superclass:
public SomeClass(int x) {
super(x);
super.someMethod(); // even if we would have overridden someMethod(),
// this will call the one from the superclass
}
Here's one instance where you would need the 'this' keyword:
public class Pong {
public int xCoordinate;
public int yCoordinate;
public Pong (int xCoordinate, int yCoordinate) {
this.xCoordinate = xCoordinate;
this.yCoordinate = yCoordinate;
}
}
I'm writing a program that will need to use a limited set of Points to process an image. I figure that I would implement it as an immutable/singleton style class. Before going on to build more of the complex logic surrounding the class I wanted to get an opinion about the core class.
import org.apache.commons.lang3.builder.HashCodeBuilder;
import java.util.HashMap;
public class Point {
private final int x,y;
private final int hashCode;
private static final HashMap<int[],Point> points = new HashMap<>();
private Point(int x,int y){
this.x = x;
this.y = y;
this.hashCode = new HashCodeBuilder().append(x).append(y).toHashCode();
}
public static Point getPoint(int x,int y){
int [] candidate = new int[]{x,y};
if(points.containsKey((candidate))){
return points.get(candidate);
}
Point newPoint = new Point(x,y);
points.put(candidate, newPoint);
return newPoint;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
#Override
public int hashCode(){
return hashCode;
}
#Override
public boolean equals(Object p){
return this == p;
}
}
I'm going to be using the class to do at least the following functions:
Map different channels in an image by this Point class
Define some static cached custom NavigableSets for ease of traversal
Various Helper functions. In example, get all Points surrounding a Point
Given the information provided, what are some downsides of the provided implementation?
Note: Putting the bulleted list before the code block breaks the display of the code block. Bug?
I think your caching "singletony" stuff may be pointless.
It doesn't save on object creation, as you will always create a candidate[] each time you ask for a Point. And, unless the Point gets reused, you use the memory for candidate and the Map.Entry in your HashMap. So, very roughly speaking, unless each Point gets reused three times, your caching uses more memory. And it always uses a more time.
If you don't cache, change your equals of course.
p.s. the rest seems fine, and immutable is good. You could consider making x and y public final to be more compatible with other Point implementations.
If you are worried about the occupied memory, there is another way to deal with it.
I assuming you have limited dimension for your points, I would suggest to combine your x & y in one variable of long (in case your dimensions is 32 ints long), or even int (if you can fit one dimensions in 16 bit), this way you'll get boost in performance & memory.
Other option is to use int[] array of your coordinates for a point, although that would take more space (since you would have to keep additional pointer reference).
Factory method in your implementation, will work only on single threaded applications, if you have multiple threads creating points, you would need to have some concurrency control in place. This would eat up your resources, because you would effectively need to lock on each point creation.
Another reason, why this Factory method is a bad idea, is that int[] arrays do not override equals and hashCode, you can try to create 2 arrays with same content, to check. So your HashMap would not simply work, and instead of saving memory you would not only create a new Point each time, but also add an entry to your HashMap and perform unnecessary calculations.
So either use Java primitives, or just create a new immutable Point each time if you need too, and go with it, don't overcomplicate with factoryMethods.
You had the right idea of making the Point class immutable but then you went and complicated things with the instance cache. It is not thread safe and it will leak memory because once a Point is created it will forever stay in the hashmap and will never be garbage collected.
Why not keep it simple and make a regular boring value class? Your IDE will even generate it for you.
Then, if you really really really want to have an instance cache, use Guava's Interner class instead of rolling your own. The result will look something like this:
public class Point {
final int x;
final int y;
private Point(int x, int y) {
this.x = x;
this.y = y;
}
static Interner<Point> instanceCache = Interners.newWeakInterner();
public static Point of(int x, int y) {
return instanceCache.intern(new Point(x,y));
}
public int getX() { return x; }
public int getY() { return y; }
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point other = (Point) o;
return this.x == other.x && this.y == other.y;
}
#Override
public int hashCode() { return x * 31 + y; }
}
I was wondering what the best way of documenting this potential Point class is:
public class Point {
/* the X coordinate of this point */
private int x;
/* the Y coordinate of this point */
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
My concrete concern lies with the repetition between the x and y attributes and their respective getters and setters, as well with the constructor arguments.
It's not that I'm developing a public API or anything of the likes, it's no problem for me to have a general comment regarding some variable and then having the getter and setter have just the same text, for instance. I'd just like to avoid comment repetition in my own internal code. Is there a way to tie getX() and the int x argument of the constructor to the x attribute, for instance?
Thanks
Is there a way to tie getX() and the int x argument of the constructor
to the x attribute, for instance?
No, not that I'm aware of. What I do:
don't comment getters (or setters) at all
if X needs contextual information and if it somehow represents (part of the) state of the class I document it in the class-level Javadoc only
One obvious convention would be not writing JavaDoc comments for trivial getters.