Private instantiation of generics - java

I'm a bit new to Java, but I'm really confused as to why these two "equivalent" statements throw different errors:
public class SampleArray<T> implements Grid<T> {
public int x;
public int y;
private List<List<T>> grid = new ArrayList<List<T>>();
public SampleArray(int x, int y) {
this.x = x;
this.y = y;
}
}
This works fine, from understanding it instantiates a class that accepts generic type T and has properties x, y, and a private property List that takes List and T
public class SampleArray<T> implements Grid<T> {
public int x;
public int y;
private List<List<T>> grid;
public SampleArray(int x, int y) {
this.x = x;
this.y = y;
List<List<T>> this.grid = new ArrayList<List<T>>();
}
}
This gives me an error, specifically:
Syntax Error insert ";" to complete LocalVariableDeclarationStatement;
Syntax Error insert "VariableDelarators" to complete LocalVariableDeclaration
Right next to the angle bracket at T>> this.grid. Why am I getting this error? Are they not equivalent just one is being instantiated in different places? The interface Grid is just a generic interface

The second piece of code has bad syntax. You should not re-specify the data type when initializing this.grid; the compiler will think you are declaring a local variable, and this can't be used in creating a local variable.
Remove the data type on the variable.
this.grid = new ArrayList<List<T>>();

you're defining grid in the constructor again. Try this
public SampleArray(int x, int y) {
this.x = x;
this.y = y;
this.grid = new ArrayList<List<T>>();
}
instead. It will declare grid in your class as private field. The initialization is done in the constructor.
The line
private List<List<T>> grid = new ArrayList<List<T>>();
defines and initializes grid in one turn.

Related

How to make a class operate with math operation in java? [duplicate]

This question already has answers here:
Operator overloading in Java
(10 answers)
Closed 5 years ago.
I have the following class, which describe one point on XY surface:
class Point{
double x;
double y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
}
So I want to overlad + and - operators to have possibility write run following code:
Point p1 = new Point(1, 2);
Point p2 = new Point(3, 4);
Point resAdd = p1 + p2; // answer (4, 6)
Point resSub = p1 - p2; // answer (-2, -2)
How can I do it in Java? Or I should use methods like this:
public Point Add(Point p1, Point p2){
return new Point(p1.x + p2.x, p1.y + p2.y);
}
Thanks in advance!
You cannot do this in Java. You'd have to implement a plus or add method in your Point class.
class Point{
public double x;
public double y;
public Point(int x, int y){
this.x = x;
this.y = y;
}
public Point add(Point other){
this.x += other.x;
this.y += other.y;
return this;
}
}
usage
Point a = new Point(1,1);
Point b = new Point(2,2);
a.add(b); //=> (3,3)
// because method returns point, you can chain `add` calls
// e.g., a.add(b).add(c)
Despite you can't do it in pure java you can do it using java-oo compiler plugin.
You need to write add method for + operator:
public Point add(Point other){
return new Point(this.x + other.x, this.y + other.y);
}
and java-oo plugin just desugar operators to these method calls.
There is no operator overloading in Java. Apparently for reasons of taste. Pity really.
(Some people will claim that Java does have overloading, because of + with String and perhaps autoboxing/unboxing.)
Let's talk about value types.
Many early classes (and some later ones) make a right mess of this. Particularly in AWT. In AWT you should be explicitly making copies of simple values all over the place. Almost certainly you want to make value types immutable - the class should be final and it should never change state (generally all final fields pointing to effective immutables).
So:
public final class Point {
private final int x;
private final int y;
private Point(int x, int y) {
this.x = x;
this.y = y;
}
public static of(int x, int y) {
return new Point(x, y);
}
public int x() {
return x;
}
public int y() {
return y;
}
public Point add(Point other) {
return of(x+other.x, y+other.y);
}
// Standard fluffy bits:
#Override public int hashCode() {
return x + 37*y;
}
#Override public boolean equals(Object obj) {
if (!(obj instanceof Point)) {
return false;
}
Point other = (Point)obj;
return x==other.x && y==other.y;
}
#Override public String toString() {
return "("+x+", "+y+")";
}
}
The original code was confused between int and double, so I've chosen one. If you used double you should exclude NaN. "Point" tends to imply an absolute point, which doesn't make sense to add. "Vector" or "dimension" would probably be more appropriate, depending upon what you intend.
I've hidden the constructor, as identity is not important. Possibly values could be cached. Possibly it is, say, common to add a point to a zero point, so no points need to be created.
It's possible you might want a mutable version, for example to use as an accumulator. This should be a separate class without an inheritance relationship. Probably not in simple cases, but I'll show it anyway:
public final class PointBuilder {
private int x;
private int y;
public PointBuilder() {
}
public PointBuilder(Point point) {
this.x = point.x;
this.y = point.y;
}
public Point toPoint() {
return new Point(x, y);
}
public PointBuilder x(int x) {
this.x = x;
return this;
}
public PointBuilder y(int y) {
this.y = y;
return this;
}
public PointBuilder add(Point other) {
this.x += other.x;
this.y += other.y;
return this;
}
}
You cannot do this in Java because there is no operator overloading in Java.
You have to use the second option you have mentioned:
Edit: You can add the Add method in the Point class itself
public Point Add(Point other){
return new Point(this.x + other.x, this.y + other.y);
}
You cannot overload operators in java. You will need handle this in Point class.
You cannot override operators in Java. That's one of the reasons why any nontrival math (especially geometric) operations should not be implemented in Java (the Point class above is kind of such a class, if you want it to do some real work, for example a line-line intersection, you'd better do it in C++).

New Instances of Objects Set to Identical Values

public class TriVal {
private static int x;
private static int y;
private static int z;
TriVal(int x, int y, int z) {
TriVal.x = x;
TriVal.y = y;
TriVal.z = z;
}
public int sum(TriVal p2) {
int a = Math.abs(TriVal.x + p2.x);
int b = Math.abs(TriVal.y + p2.y);
int c = Math.abs(TriVal.z + p3.z);
int sum = a + b + c;
return sum;
}
}
This is a piece of a constructor for an object that contains a set of 3 values.
However, I am writing a function that creates a new TriVal made by summing the x, y, and z, of two instances of this object.
So say we have
TriVal p1 = new TriVal(10, 10, 10);
TriVal p2 = new TriVal(20, 20, 20);
calling the function
p1.sum(p2)
(Which is included elsewhere in the class) should return 90.
However, it returns 120.
I am learning that upon creating a new instance of the TriVal Object, the previously defined p1 instance is somehow being set to the same values as p2, which explains the sum being 120.
I believe this error is located somewhere in my constructor, perhaps in the way I am updating values or declaring variables at the top of the class?
Any helpful tips would be appreciated, thank you!
private static int x;
private static int y;
private static int z;
You declared your instance member as static which will be same for all the instances. They store last assigned values. remove static and you'll be fine.
As #Orin pointed, you'll need to change the code a bit where you should bind your parameters to instance members.

How to get a value from an array to be used in another class?

If there is an array such as:
//....
int[] anArray;
anArray = new int[3];
anArray[0] = new otherClassWConst( x, y , z);
anArray[1] = new otherClassWConst( x, y , z);
anArray[2] = new otherClassWConst( x, y , z);
//....
With the values of x and y and z all being of different value to the other x, y, and z's from the other objects in the array. (Does that make sense? Like the value of x in anArray[0] is not the same as the value found in anArray[2]). Note: there is a constructor from another class that requires those parameters, I'm not sure if thats important
How do I, in a different class, get the value of one of the parameters (for example, the value of y) in each of the array values. As in, is there a way I can get all three values of the Ys so I can add them all up together in another class?
For example
//code attaining only the y values of the array
overallValueOfY = Y + Y + Y; // or something of that nature
//life continues over here.
Please tell me if something is unclear, I tried so hard to explain. Thank you for the consideration.
OtherClassConst will need to supply a get method for it:
public class OtherClassConst {
private int x;
private int y;
private int x;
public (int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
}
public int getY() {
return y;
}
/* Same concept for getX() and getZ() */
}
Then, you class can call it:
int sumY = 0;
for (OtherClassConst c : myArray) {
sumY += c.getY();
}
First off, your array won't work unless your new class extends Int, I just want to make sure you know that.
Now, all you have to do is in that new class create an int varriable
int x;
int y;
int z;
and set them equal to what is put in the constructor. Then create a new method that returns the values
public int getX(){
return this.x;
}
public int getY(){
return this.Y;
}
public int getZ(){
return this.Z;
}
You need to create POJO for your other class with x,y and z instance variables, then using setter method of y you can get the values. Iterate over them to get the sum of values.
If you other OtherClass has a getY method that returns an integer then you can use the following to sum them:
Arrays.stream(anArray).mapToInt(OtherClass::getY).sum();
It is worth getting use to using streams rather than for loops.

Java add object to list

Im currently using the following code
Panel class
static List<Shoots> bullets;
public Panel() {
bullets = new ArrayList<>();
setBorder(BorderFactory.createLineBorder(Color.black));
}
Another class
Panel.bullets.add(new Shoots(1, Panel.headx, Panel.heady));
class Shoots {
private int speed;
private int x;
private int y;
public Shoots(int speed, int x, int y) {
this.speed = speed;
this.x = x;
this.y = y;
getX();
}
public int getX() {
return this.x;
}
}
Then when I try to System.out.println(Panel.bullets); I get
[]
How can I do this the proper way?
bullets arraylist is empty i.e. zero elements. Thats why you are getting that output.
Also, your list is static and you are asssigning the values everytime in the constructor. That will create a new arraylist and assign it to bullets variable everytime an object is created. Also, you aren't adding anything into the list.
Did you add anything into bullet list before using? Every time you initialize it inside constructor. so Every new object of Panel class will initialize it and do empty. so create and initialize at class level. i.e.
static List<Shoots> bullets= new ArrayList<>();

Array overwriting all other values when a new one is added

I have been having an issue when adding objects to an array. It seems that every single time I add a new WoodFloor object to the array, it overwrites all of the other values of the array. Here's my code:
package code;
public class Main {
private static Block[] blocks = new Block[12];
public static void main(String[] args) {
for(int i = 0; i < 12; i++) {
blocks[i] = new WoodFloor(i * 10, i * 20);
}
}
}
package code;
public class Block {
protected static int x, y;
public Block(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
package code;
public final class WoodFloor extends Block {
public WoodFloor(int x, int y) {
super(x, y);
}
}
Don't use static modifier for class fields that need to be different for each instance. The static modifier makes the field a class field, one that is effectively shared by all instances, and this is not what you want.
So change this:
protected static int x, y;
to this:
protected int x, y;
Your program produces 12 different objects, but they all reference the same pair of x and y. The problem is on this line:
protected static int x, y;
// ^^^^^^
When you make a field static, you are saying that the value of this field is going to be the same in every single object of the class. This is definitely not what you are trying to achieve here: you need each WoodFloor to have its own x and y. For that, you use instance fields (i.e. fields declared without static).
Static makes the variable available at the class lever so an instance is not needed to access it. Here effectively resets it to its original value each time rather than moving to the next array position and forgets the old array.
I'm suspecting it's the 'static' keyword for x and y.

Categories

Resources