Errors with closing braces/semicolons - java

I've got two compile errors in one of my classes and I don't understand why they're there.
The top error is saying there needs to be another semi-colon and the bottom one says it needs another closing brace.
The bottom error disappears if i put in another curly brace but the top one doesn't. Any ideas?
(This is probably a case of me being blind/stupid so i apologise in advance :)
package com.pathfinding;
import java.util.ArrayList;
public class EdgeNodeFactory
{
static boolean[][] edgeMatrix = new boolean[100][100];
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
edgeMatrix[i][j] = false;
}
}
static ArrayList<Node> nodes = new ArrayList<Node>();
static ArrayList<Edge> edges = new ArrayList<Edge>();
static int edgeCount = 0;
static int nodeCount = -1;
}

You've tried to put code (the for loop) directly in your class - it's not in a constructor, a method, or a static/instance initializer. That's not valid. When do you want that code to be executed?
I suspect your code should really look like this:
public class EdgeNodeFactory
{
private boolean[][] edgeMatrix = new boolean[100][100];
private int edgeCount = 0;
private int nodeCount = -1;
private List<Node> nodes = new ArrayList<Node>();
private List<Node> edges = new ArrayList<Edge>();
public EdgeNodeFactory()
{
// You *could* put your for loop here... but the array
// elements will all be false anyway, as that's the default...
// If you don't need any code in this constructor, and you
// don't declare any other constructors, you can remove it
// entirely - the compiler will create it by default.
}
// Other methods here
}
Note how I've made all the fields private and non-static... you should almost certainly be creating an instance of EdgeNodeFactory rather than using static fields, and you should almost always make fields private.

Has been a while since I did any Java, but I believe that for loop should be inside a method or function of some description, rather than the class declaration.
I would imagine you mean that to be in a constructor.

I think what the for loops are meant to do is initialization of static array field. In this case you should put the code in a static initializer like this:
package com.pathfinding;
import java.util.ArrayList;
public class EdgeNodeFactory
{
static boolean[][] edgeMatrix = new boolean[100][100];
static {
for (int i = 0; i < 100; i++)
{
for (int j = 0; j < 100; j++)
{
edgeMatrix[i][j] = false;
}
}
}
static ArrayList<Node> nodes = new ArrayList<Node>();
static ArrayList<Edge> edges = new ArrayList<Edge>();
static int edgeCount = 0;
static int nodeCount = -1;
}
The code inside static { ... } at the class level is executed the first time the class is loaded (only once). This means it will be executed before any instances of the class are created and before any other code can access the class.
It remains debatable whether the fields should be static, but if you're sure they should, this is how you should initialize them.

Related

Individually/separately instantiated objects using the same data structure

Note: This is a troubling problem, possibly a bug, although I might be incorrect and missing something small
Problem:
Issue is the separately instantiated objects are referring to the same data structure.
Calling a.add() adds an object to data[NEXT], where is instantiated to NEXT = 0, followed by NEXT++ for increment purposes.
Thereafter, b.add() is called, and following the logic of the add() method, the array is extended,
BUT no initial value has been inserted into b i.e. b.data[0] = null
TL;DR
a.add() adds value to a.
b.add() extends a's array. This should not happen as a and b are 2 separate objects of the same type
main class code:
//...
SimpleSet<Integer> a = new SimpleSet<>();
SimpleSet<Integer> b = new SimpleSet<>();
// add a maximum of 20 unique random numbers from 0..99
Random rand = new Random();
for (int i = 0; i < 20; i++) {
a.add(rand.nextInt(100)); //i=0 - adds to data[0] with no issue
b.add(rand.nextInt(100)); //i=0 - extends a's array? why?
}
//...
class SimpleSet
public class SimpleSet<E> {
private static int MIN_SIZE = 1;
private static int NEXT = 0;
private Object[] data;
/**
* constructor of SimpleSet
*/
public SimpleSet() {
data = new Object[MIN_SIZE];
}
public void add(E e) {
if(NEXT > 0.75*MIN_SIZE){
extendArray();
}
if (data != null) {
data[NEXT] = e;
NEXT++;
}
}
private void extendArray() {
MIN_SIZE = MIN_SIZE*2;
Object[] newData = new Object[MIN_SIZE];
for (int i = 0; i < data.length; i++) {
newData[i] = data[i];
}
data = newData;
return;
}
//...
}
Am I missing something small or is this a bug?
IDE = IntelliJ 2016.3

Java: How to use functions of a class which has been instantiated by ArrayList

Here is just a simple example. Obviously there are simpler ways to set everything up within the constructor, but the arrayList I'm actually working with has already been set up, I just need to change individual sections of it. There HAS to be a way to call a class's functions in ArrayList, but for the life of me I can't figure out how.
import java.util.ArrayList;
public class ArrayTest{
public static void main(String[] args){
//Here's an example of a regular array:
Length[] lArray = new Length[3];
for (int i = 0; i < 3; i++){
lArray[i].setLength(i + 1);
}
//Here's how I was hoping ArrayList would function:
ArrayList<Length> lList = new ArrayList<Length>(3);
for (int i = 0; i < 3; i++){
lList[i].setLength(i + 1);
// --OR--
lList.setLength(i, i + 1);
}
}
}
Here's the length class:
public class Length{
private int length;
Length(){
length = 0;
}
Length(int s){
length = s;
}
public void setLength(int s){
length = s;
}
}
Thanks!
You add elements to the ArrayList with add.
Since it's an ArrayList<Length>, you add Length objects:
lList.add(new Length());
And in your specific loop :
ArrayList<Length> lList = new ArrayList<Length>(3);
for (int i = 0; i < 3; i++){
Length l = new Length();
l.setLength(i+1);
lList.add(l);
}
BTW, the array initialization is also missing an important initialization :
for (int i = 0; i < 3; i++){
lArray[i] = new Length(); // added
lArray[i].setLength(i + 1);
}
If the ArrayList already contains the elements, and you just want to modify them, you can write something like this:
lList.get(i).setLength(i + 1);
assuming that the ArrayList contains the ith element.
You could create a method with your operation/algorithm like
public void foo(){
System.out.println("some algorithm!");
}
inside Length class. This will operate on each instance of Length class.
And for iterating, you can use
ArrayList<Length> lList = new ArrayList<Length>(3);
for (Length l : lList){
l.foo();
}
This will call everything you code inside foo.

Final and Immutable Variable Changes in Java

I have a Path class which I think is immutable. In another class called Test, I have a final reference to an object of Path.
Yet, in between the constructor and the getter method, the Path object changes even though it is immutable and the reference is final. I know this because the length of the int array node in Path changes from the constructor to the getter. It seems as it the object is a completly different one altogether.
My program is multi-threaded but I've tried it with a single thread and that didn't resolve the problem.
Here is the immutable Path class
public class Path implements Iterable<Point> {
private final int[] nodes;
private final double distance;
public Path(Scenario scenario, int gateway, int sensor){
this.scenario = scenario;
nodes = new int[2];
nodes[1] = -gateway - 1;
nodes[0] = sensor;
distance = scenario.DISTANCE_GATEWAY_SENSOR[gateway][sensor];
}
public Path(Path base, int newSensor){
scenario = base.scenario;
//Copy the old path. These are rigid structures so that we do not need to deep copy
nodes = new int[base.nodes.length + 1];
for(int i = 0; i < base.nodes.length; i++)
nodes[i + 1] = base.nodes[i];
nodes[0] = newSensor;
distance = base.distance + scenario.DISTANCE_SENSOR_SENSOR[newSensor][nodes[1]];
}
public Path(Scenario scenario, int[] nodes, boolean isSensor, double distance){
this.scenario = scenario;
this.distance = distance;
this.nodes = Arrays.copyOf(nodes, nodes.length);
if(!isSensor)
for(int i = 0; i < this.nodes.length; i++)
this.nodes[i] = -this.nodes[i] -1;
}
#Override
public Iterator<Point> iterator() {
return new PointIterator();
}
public class PointIterator implements Iterator<Point>{
private int next = -1;
#Override
public boolean hasNext() {
return next + 1 < nodes.length;
}
#Override
public Point next() {
int p = nodes[++next];
if(p >= 0)
return scenario.SENSOR_LOCATION[p];
return scenario.CS_LOCATION[-p - 1];
}
#Override
public void remove() {
throw new IllegalAccessError("This method is not supported");
}
}
}
and here is the Test class (with a final reference to the Path class)
public class Test {
private final Path gatewayTour;
public Test(Scenario scenario, boolean[] chosenGateway){
distanceFitness = 0;
Point current = scenario.SINK_LOCATION;
boolean visited[] = new boolean[scenario.CONFIG.NUM_CS];
int nextGateway;
LinkedList<Integer> order = new LinkedList<>();
do {
double minimumDistance = Double.MAX_VALUE;
nextGateway = -1;
for(int i = 0; i < scenario.CONFIG.NUM_CS; i++)
if(!visited[i] && CHOSEN_GATEWAYS[i] && scenario.CS_LOCATION[i].isCloserThan(minimumDistance, current)) {
nextGateway = i;
minimumDistance = scenario.CS_LOCATION[i].distance(current);
}
if(nextGateway >= 0) {
distanceFitness += minimumDistance;
visited[nextGateway] = true;
order.add(nextGateway);
current = scenario.CS_LOCATION[nextGateway];
}
} while(nextGateway >= 0);
int path[] = new int[order.size()];
Iterator<Integer> it = order.iterator();
for(int i = 0; i < order.size(); i++)
path[i] = it.next().intValue();
gatewayTour = new Path(scenario, path, false, distanceFitness);
}
public Path getGatewayTour(){
//Here, the gatewayTour object has changed and does not have the same content as in the constructor
return gatewayTour;
}
}
Is there anything in my program that permits the object to change? I'll be more precise: is there anything that woud permit the int array "nodes" in Path class to change length? Because this is the real problem.
[EDIT]: My test was flawed, which led me to believe that the value of my 'nodes' array changed. Thanks to all who pointed flaws or possible improvements in my code.
I'll accept the answer of AlexR because he pointed out that one could change individual elements in a final array; something I didn't know and that help resolve the problem.
Word final means that the reference marked with this word cannot be changed. It does not mean that the referenced object cannot be changed.
This means that there is no problem to change the instance of Path by changing its fields. Yes, you are right, your fields are final too. But let's examine them:
private final int[] nodes;
private final double distance;
private final Scenario scenario;
distance is a primitive, so it indeed cannot be changed once assigned during initialization. nodes is an array, i.e. object. The array itself cannot be changed, i.e. the reference refers to the same array. However you can change elements of the array.
scenario is object too. You have not sent the class Scenario here, but again if fields of this class can be changed this object can be changed.
private final int[] nodes;
Is still mutable, assuming your constructor simply copies the array reference.
public Path(int[] nodes, double distance) {
this.node = nodes;
this.distance = distance;
}
This is because Path's nodes is still pointing to the instance that was passed in. If that instance changes, then your Path's state has changed.
One solution is to make a copy of node in the constructor (using System.arraycopy).
To be sure the answer is correct we need to see more code; it's not clear what is being changed where. However, if the idea is to guarantee that nodes is unmodifiable, a primitive array (final or not) will not work. Something more like
private final List<Integer> nodes;
public Path(Integer[] array /* note boxed as Integer */) {
nodes = java.util.Collections.unmodifiableList(
java.util.Arrays.asList(array));
/* etc. */
}
Problem here!
public Path(Scenario scenario, int[] nodes, boolean isSensor, double distance){
this.scenario = scenario;
this.distance = distance;
this.nodes = nodes;
You copy the nodes array reference.
Use:
this.nodes = Arrays.copy(nodes, 0, nodes.length);
If you modify the array, changes will be reflected into Path! Similarly, if you modify the array in the constructor, changes will be reflected to the caller...
As such, your class is NOT immutable at the moment. Also, "real" (to my sense) immutable classes are final themselves.

Array of queues not compiling - cannot find symbol error

I'm trying to get a radix sort going with an array of queues to avoid long rambling switch statements but I'm having some trouble getting the array properly initialized. The constructor and an example of an implementation are given below.
I'm just getting a cannot find symbol error when I try to compile though.
public static radixj(){
IntQueue[] buckets = new IntQueue[10];
for (int i = 0; i < 10; i++)
buckets[i] = new IntQueue();
}
public static void place(int temp, int marker)
{
int pos = temp % marker;
buckets[pos].put(temp);
}
I'm pretty sure it is a really simple mistake that I'm making but I can't find it. Any help would be greatly appreciated.
In your code
IntQueue[] buckets = new IntQueue[10];
is a local variable to the function
public static radixj()
which must have a return type
public static void radixj()
So then you can't use it in another function
buckets[pos].put(temp);
You should declare a static class variable
class Foo {
static IntQueue[] buckets = new IntQueue[10];
...
and access it using: Foo.buckets
class Foo {
public static IntQueue[] buckets = new IntQueue[10];
public static void radixj() {
for (int i = 0; i < 10; i++) {
Foo.buckets[i] = new IntQueue();
}
}
public static void place(int temp, int marker) {
int pos = temp % marker;
Foo.buckets[pos].put(temp);
}
}
the return type in radixj() is missing and buckets cannot be resolved to a variable

Java - How to declare table[i][j] elements as instance variables?

All,
I am trying to code a Connect4 game. For this, I have created a P4Game class and a P4Board class which represents the i X j dimensions of the Connect4 board.
In P4Game, I have the following:
public class P4Game{
//INSTANCE VARIABLES
private int nbLines;
private int nbColumns;
private P4Board [][] position;
//CONSTRUCTOR
public P4Game(int nbLines, int nbColumns){
this.nbColumns = nbColumns;
this.nbLines = nbLines;
P4Board [][] position = new P4Board [nbLines][nbColumns]; //Creates the table to receive the instances of the P4Board object.*/
for (int i=0; i<nbLines; i++){
for (int j=0; j<nbColumns; j++){
this.position[i][j] = new P4Board(i,j); //Meant to create each object at (line=i, column=j)
}
}
}
This causes a NullPointerException in the nested loops where I mention this.position[i][j]. I reference those objects in other methods of this class so I need them to be instance variables. I suppose the exception is due to the fact that I have not listed the table element position[i][j] as an instance variable at the beginning of the class.
my question to people here is (1) is my assumption correct, and if so (2) what would be the syntax to declare instance variables of this form?
Thank you all for your help with what I realize is a very basic question. Hopefully it will also benefit other newbies.
Cheers,
JDelage
See added comment inlined... You code is fine except for one little detail, where you're creating a new position variable where you actually mean to use the instance variable.
public class P4Game{
//INSTANCE VARIABLES
private int nbLines;
private int nbColumns;
private P4Board [][] position;
//CONSTRUCTOR
public P4Jeu(int nbLines, int nbColumns){
this.nbColumns = nbColumns;
this.nbLines = nbLines;
// You're creating a LOCAL variable called position here if you don't comment what's commented:.
/*P4Board [][] */position = new P4Board [nbLines][nbColumns]; //Creates the table to receive the instances of the P4Board object.*/
for (int i=0; i<nbLines; i++){
for (int j=0; j<nbColumns; j++){
this.position[i][j] = new P4Board(i,j); //Meant to create each object at (line=i, column=j)
}
}
}
}
Your assumption is incorrect.
In the constructor, you're making a local variable with the same name as the field. (By writing P4Board [][] position = ...) This creates a local variable and does not affect the field, which remains uninitialized. You need to remove the P4Board [][] to change it from a variable declaration to an assignment of the existing field. (Just like you write this.nbLines = ... to assign the field)
You're redefining P4Board [][] position in the constructor and then calling this.position which is not initialized (i.e. null).
Look out carefully! You are hiding the instance variable > P4Board [][] position = new P4Board [nbLines][nbColumns];
As others have said you are hiding the instance variable with a local variable. You should really check out checsktyle as it has checks to tell you if you have made such a mistake. Two other tools are PMD and FindBugs.
Your assumption is incorrect. Try looking a few lines higher for the bug in your homework.
This runs for me. I substituted into for P4Board, since you didn't supply it:
public class P4Game
{
private int nbLines;
private int nbColumns;
private int [][] position;
public static void main(String[] args)
{
P4Game game = new P4Game(3, 3);
System.out.println(game);
}
public P4Game(int nbLines, int nbColumns)
{
this.nbColumns = nbColumns;
this.nbLines = nbLines;
this.position = new int[this.nbLines][this.nbColumns];
for (int i=0; i < this.nbLines; i++)
{
for (int j=0; j < this.nbColumns; j++)
{
this.position[i][j] = i+j;
}
}
}
public String toString()
{
StringBuilder builder = new StringBuilder(1024);
builder.append('[');
for (int i = 0; i < this.nbLines; ++i)
{
builder.append('{');
for (int j = 0; j < this.nbColumns; ++j)
{
builder.append(this.position[i][j]).append(',');
}
builder.append('}');
}
builder.append(']');
return builder.toString();
}
}

Categories