I'm trying to add a method an an array like this.
Position[] positions = new Position[10];
Position pos = positions.getPosAt(x, y);
I know this can be accomplished like:
Position pos = getPosAt(positions, x, y)
But I would like to know if there is a way to accomplish the first method.
you can make a class handler for this, like this PositionArray class (name it as you would like):
public class Test {
public static void main(String... args) {
Position[] positions = new Position[10];
positions[0] = new Position(5, 10);
positions[1] = new Position(11, 18);
positions[2] = new Position(20, 7);
PositionArray pa = new PositionArray(positions);
System.out.println(pa.getPosAt(5, 10)); // Position{x=5, y=10}
}
}
class PositionArray {
private Position[] positions;
public PositionArray(Position[] positions) {
this.positions = positions;
}
public Position getPosAt(int x, int y) {
for (Position p : positions) {
if (!Objects.isNull(p)) {
System.out.println(p.getX() + " " + p.getY());
if (p.getX() == x && p.getY() == y) {
return p;
}
}
}
return null;
}
}
class Position {
private final int x;
private final int y;
public Position(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
#Override
public String toString() {
return "Position{" + "x=" + x + ", y=" + y + '}';
}
}
There is no way to do this in Java. You could possibly create your own class that contained an array of Position objects and provides e.g. get methods, but there is no way whatsoever to add methods to classes you do not control, including all array types.
Related
I need a java program that can solve the following issues:
1- It has a data structure (DS) to represent the following data where rows and columns are indexed by Strings and cells values are booleans.
So that, to access row (i), I can simply say DS["Yi"] and to access a particular cell (j) in row (i) I can say DS["Yi","Xj"]
2- The column indexs {"X1", "X2", "X3", ..., "Xn"} has to be populated from a class fields. For example consides the following class:
public class Test {
private String X1;
private String X2;
private String X3;
private String X4;
private String X5;
}
For this class, my table's column is going to be {"X1", "X2", "X3", "X4", "X5"}, and if I later update class Test to include one more field, let's say "X6", then DS has to automatically include this new field.
3- Finally, I want to save these data into a file {TXT, XML, or JSON} so that every time the code runs, it can read the values from the file.
I think the easiest thing to do might be to have some convention whereby you can internally convert known row and column labels into numerical indices. Then, you could just use a plain 2D boolean array.
If you can't do this, then one option would be to use a map of maps, something like this:
Map<String, Map<String, Boolean>> grid = new HashMap<>();
// populate first row
grid.put("Y1", new HashMap<>());
grid.get("Y1").put("X1", true);
grid.get("Y1").put("X2", true);
grid.get("Y1").put("X3", false);
// ... other columns
grid.get("Y1").put("Xn", true);
Give it a try with this approach.
N.B.: this code is not tested. Here I've used both int index search on array because I will assume the the list for example "x1", "x2", "x3" is not necessarily to be arranged(probably you can try with Map)
public class SS {
public static void main(String[] args) {
//Used for indexing
List<String> listX = Arrays.asList("x1", "x2", "x3");
List<String> listY = Arrays.asList("y1", "y2", "y3");
//Used to fetch boolean value which is indexed arr[x][y] with the value defined in the class YourClass
YourClass[][] arr = new YourClass[listX.size()][listY.size()];
int i=0;
for (String y : listY) {
int j=0;
for (String x : listX) {
//Fill the array
arr[i][j] = new YourClass(new Random().nextInt(1), x, y);
j++;
}
i++;
}
//To get DS["x2", "y3"]
DS ds = new DS("x2", "y3");
i=0;
for (String y : listY) {
if(ds.getY().equals(y))
{
int j=0;
for (String x : listX) {
if(ds.getX().equals(x))
System.out.println(arr[i][j].toString());
j++;
}
}
i++;
}
}
}
//class to maintain index positions
class YourClass{
int a;
String x;
String y;
public YourClass(int a, String x, String y) {
this.a = a;
this.x = x;
this.y = y;
}
#Override
public String toString() {
return "YourClass{" +
"a=" + a +
", x='" + x + '\'' +
", y='" + y + '\'' +
'}';
}
public int getA() {
return a;
}
public void setA(int a) {
this.a = a;
}
public String getX() {
return x;
}
public void setX(String x) {
this.x = x;
}
public String getY() {
return y;
}
public void setY(String y) {
this.y = y;
}
}
//class used to search the element
class DS {
String x;
String y;
public String getX() {
return x;
}
public void setX(String x) {
this.x = x;
}
public String getY() {
return y;
}
public void setY(String y) {
this.y = y;
}
public DS(String x, String y) {
this.x = x;
this.y = y;
}
}
Problem Statement:
A fish has to move in a 2D Aquarium.
At no point two fishes can be at the same Location.
Challenges:
To generate a random direction in which every fish will move.
Fish should not go beyond the Aquarium specifications.
Maintaining a collection which contains the locations of all fishes in the aquarium.
Approach:
I used multi threading via Java so that all the fishes can move at the same time.
Used Enum's to extract direction for X & Y co-ordinates randomly.
Created a Fish Class which extends Location Class.
Please suggest if there could have been a different approach used for this question since I am an Intermediate Level Java Programmer.
Location Class
public class Location {
public int x;
public int y;
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + x;
result = prime * result + y;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
Location other = (Location) obj;
if (x != other.x)
return false;
if (y != other.y)
return false;
return true;
}
public Location(int Size) {
setRandomLocation(Size);
synchronized (Aquarium.location_list) {
Aquarium.location_list.add(this);
}
}
public Location() {
}
public void setRandomLocation(int Size){
int location_exist_ind=0 ;
while(location_exist_ind==0){
this.x = (int)(Math.random() * Size);
this.y = (int)(Math.random() * Size);
location_exist_ind=checkLocation(this);
}
}
public int checkLocation(Location obj){
int temp_ind=0;
synchronized (Aquarium.location_list) {
if(Aquarium.location_list.size()!=0)
for(Location loc1 : Aquarium.location_list )
{
if(obj.equals(loc1)){
System.out.println("This location" + obj.x
+ " , "
+obj.y+ " is already taken by another fish , so generating the random location again.");
temp_ind=0;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
break;
}
else temp_ind=1;
}
else temp_ind=1;
}
return temp_ind;
}
public void setNextLocation(int x,int y){
int X_location = 0;
int Y_location = 0;
int location_exist_ind=0 ;
while(location_exist_ind==0){
X_location= Direction_X.getRandom_direction_X(x);
Y_location= Direction_Y.getRandom_direction_Y(y);
Location temp_loc= new Location();
temp_loc.setX(X_location);
temp_loc.setY(Y_location);
location_exist_ind=checkLocation(temp_loc);
}
this.setX(X_location);
this.setY(Y_location);
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}
Aquarium class
import java.util.LinkedList;
import java.util.Scanner;
public class Aquarium {
static int size= 0;
static int number_of_fishes = 1000;
static int number_of_moves = 0;
static LinkedList<Location> location_list = new LinkedList<Location>();
public static void main(String[] args) {
Scanner scn= new Scanner(System.in);
System.out.println("Please enter the size of the aquarium :");
size=scn.nextInt();
while(number_of_fishes >= Math.pow(size,2)){
System.out.println("Please enter the correct number of fishes in the aquarium , MAx allowed fishes are 2 to the power size of Aquarium: ");
number_of_fishes=scn.nextInt();
}
System.out.println("Please enter the Number of Minimum Moves for each of the fishes :");
number_of_moves=scn.nextInt();
Fish[] fishes = new Fish[number_of_fishes];
Thread[] thr = new Thread[number_of_fishes];
for (int i=0;i<number_of_fishes;i++){
fishes[i]= new Fish(size, number_of_moves ,i);
thr[i]= new Thread(fishes[i]);
thr[i].start();
}
try {
for (int i=0;i<number_of_fishes;i++)
thr[i].join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Final Location list goes like : ");
for(Location loc : location_list){
System.out.println(loc.x + " , " + loc.y);
}
}
}
Fish class
public class Fish extends Location implements Runnable{
int moves=0;
int fishnum=0;
public Fish(int AquariumSize, int moves , int fishnum) {
super(AquariumSize);
this.moves=moves;
this.fishnum=fishnum;
}
#Override
public void run() {
for(int i=0;i< moves;i++){
if(i==0)
System.out.println(" Initial location of Fish " + fishnum + " Location is "+this.x + " , "+ this.y);
this.setNextLocation(x, y);
System.out.println(" Location of Fish " + fishnum + " Move number is "+ i + " , new location is "+this.x + " , " + this.y);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Direction enumeration
public enum Direction_X {
RIGHT(1),
NONE(0),
LEFT(-1);
public int direction_X_ind;
Direction_X(int X)
{
direction_X_ind = X;
}
public static int getRandom_direction_X(int x)
{
int X=x;
if(X!=0 && X!=Aquarium.size-1)
{
X = X + values()[(int) (Math.random() * (values().length))].direction_X_ind;
}
else if(x>=Aquarium.size-1)
{
X = X + values()[ (int) (Math.random() * (values().length-1)) + 1 ].direction_X_ind;
}
else
{
X = X + values()[(int) (Math.random() * (values().length-1))].direction_X_ind;
}
return (X);
}
}
public enum Direction_Y {
UP(1),
NONE(0),
DOWN(-1);
public int direction_Y_ind;
Direction_Y(int Y)
{
direction_Y_ind = Y;
}
public static int getRandom_direction_Y(int Y)
{
if(Y!=0 && Y != Aquarium.size-1)
{
Y = Y + values()[ (int) (Math.random() * (values().length))].direction_Y_ind;
}
else if(Y >= Aquarium.size-1)
{
Y = Y + values()[ (int) (Math.random() * (values().length-1)) + 1 ].direction_Y_ind;
}
else
{
Y = Y + values()[ (int) (Math.random() * (values().length-1))].direction_Y_ind;
}
return (Y);
}
}
Multi threading will only make your logic harder. The fishes' direction of movement is dependent on other fishes so this makes no sense letting each and every one of them move on its own with synchronization. Perhaps a better approach will be something involving a game loop. You can read more about it here. Basically its a more sophisticated implementation of an event loop.
This question already has answers here:
How do I pass a primitive data type by reference?
(8 answers)
Closed 7 years ago.
here is my code
public class Scale {
public static void main(String[] args) {
int x = 4;
int y = 3;
int faktor = 2;
skaliere(x,y,faktor);
System.out.println(x + " " + y);
}
public static void skaliere(int x, int y, int faktor){
// ?
}
}
I want to change the scale the x and y by faktor, not using a return value. Just by the skaliere method.
I want to change the scale the x and y by faktor, not using a return value. Just by the skaliere method.
Note that Java is not pass by reference, it's always pass by value.
Without any hack, simply you can't because they are primitives. If they are mutable objects, yes you can change their state.
That hack would be making them static and assigning values inside that method.
You can always make your own MutableInteger class
class MutableInteger{
private int value;
public MutableInteger(int v){
this.value = v;
}
public int get(){
return value;
}
public void set(int newValue){
this.value = newValue;
}
#Override
public String toString() {
return Integer.toString(value);
}
}
Then use it in your code:
public static void main(String[] args) {
MutableInteger x = new MutableInteger(4);
MutableInteger y = new MutableInteger(3);
int faktor = 2;
skaliere(x,y,faktor);
System.out.println(x + " " + y);
}
public static void skaliere(MutableInteger x, MutableInteger y, int faktor){
x.set(x.get() *faktor);
y.set(x.get() *faktor);
}
Since you are making your own class, you can even move the skaliere method into your MutableInteger
class MutableInteger{
...
public void skaliere(int faktor){
this.value *=faktor;
}
}
which makes your code look like this:
public static void skaliere(MutableInteger x, MutableInteger y, int faktor){
x.skaliere(faktor);
y.skaliere(faktor);
}
You don't even need the static method anymore
You could do this with an object that wraps the two values. This is because the object reference is passed to the method. If you pass a primitive which are immutable, they will never be changed on the return, it would only change a copy in the method. Using an object, you can pass the containing values and it would be the ones referenced by the main method when retrieved.
public static void main(String[] args) {
// org.eclipse.swt.graphics.Point
Point p = new Point(0, 0);
p.x = 4;
p.y = 3;
int faktor = 2;
skaliere(p,faktor);
System.out.println(p.x + " " + p.y);
}
public static void skaliere(Point p, int factor){
p.x *= factor;
p.y *= factor;
}
New to Java.
I have an instance player1 of the Player class below.
Player player1 = new Player(0,0);
Inside the Player class I have composed an object coordinate of type Coord (defined below). When I instantiate player1 above "Player is at coordinate 0,0" is displayed as expected.
public class Player extends Entity {
public Coord coordinate;
public Player(int x, int y) {
Coord coordinate = new Coord(x,y);
System.out.println(“Player is at coordinate “ + coordinate.getX() + “,”
+ coordinate.getY());
}
}
The Coord class is defined as follows.
public class Coord {
private int x;
private int y;
public Coord(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
The problem arises when I try to access obj and its respective methods after I instantiate player1. When I try to access coordinate I get a NullPointerException error.
Player player1 = new Player(0,0);
System.out.println(“Player is at coordinate “ + player1.coordinate.getX() +
“,” + player1.coordinate.getY());
What am I doing wrong?
You aren't making Coord obj; a field of your class. That could be as simple as something like
public class Player extends Entity {
Coord obj;
public Player(int x, int y) {
obj = new Coord(x,y);
System.out.println(“Player is at coordinate “ + obj.getX() + “,”
+ obj.getY());
}
}
Note that obj is a terrible field name, and that it has default level access permission here. One way to improve that might be something like
public class Player extends Entity {
private Coord coordinates;
public Player(int x, int y) {
coordinates = new Coord(x,y);
System.out.println(“Player is at coordinate “ + obj.getX() + “,”
+ obj.getY());
}
public Coord getCoordinates() {
return coordinates;
}
}
Then you could use it like
Player player1 = new Player(0,0);
System.out.println(“Player is at coordinate “
+ player1.getCoordinates().getX()
+ “,” + player1.getCoordinates().getY());
You might also override toString() in the Coord class, then you could say
System.out.println(“Player is at coordinate “
+ player1.getCoordinates());
i know that this question has been asked many types, but i am not getting trough the problem. So following. I have created a class that is creating array of 2 positions. The goal is to create point coordinates so i can generate several points later. Hier is my code
import java.util.Random;
public class Coor {
private static int[] coord;
public static int[] generate(){
coord = new int[2];
return coord;
}
public static void printX(){
System.out.println("X = " + coord[0] );
}
public static void printY(){
System.out.println("Y = " + coord[1] );
}
public static int randomFill(){
Random rand = new Random();
int randomNum = rand.nextInt(99);
return randomNum;
}
public static void main(String args[]) {
generate();
for(int i = 0; i < 2; i++){
coord[i] = randomFill();
}
printX();
printY();
}
}
So, this is working perfect, but what I want is to create the points in another class and to use them there, but I have no idea how to achieve this. I am new to java, and I have almost understood some examples in the oracle docs, but can not implement it. Can you please help me a little? I just need one example class which is obtaining the coordinates of the points, after that I can extend it alone for my needs.
You should not make your data static and you should provide a public constructor see below.
public class Coord {
private int[] coord;
public Coord(int x, int y) {
coord = new int[2];
coord[0] = x;
coord[1] = y;
}
public void printX(){
System.out.println("X = " + coord[0] );
}
public void printY(){
System.out.println("Y = " + coord[1] );
}
public static void main(String[] args) {
Coord c1 = new Coord(10, 11);
Coord c2 = new Coord(23, 14);
}
}