Lets say we have these two different constructors.
What is the different between the first one and the second one.
How is the way to do it? Explain the difference please!
(I know you cant have these two constructors in the same class, this is just to show what i mean.
public class StackOverFlow {
private int[] x; // instance variable
StackOverFlow(int[] x) { // constructor
this.x=x;
}
StackOverFlow(int[] x) { // constructor
this.x = new int[x.length];
for(int k=0 ; k < x.length; k++) {
this.x[k]=x[k];
}
}
The first constructor assigns a reference of an existing int array to the member variable. The caller of the constructor can later change the array and the change would be reflected in the instance.
The second constructor copies the array, so later changes in the passed array wouldn't change the copy stored in the instance.
int[] intArray = new intArray {1,2,3};
StackOverFlow so1 = new StackOverFlow(intArray); // assume we are using the first constructor
intArray[1]=5; // changes the array stored in `so1` object
StackOverFlow so2 = new StackOverFlow(intArray); // assume we are using the second constructor
intArray[1]=8; // doesn't change the array stored in `so2` object
In the first case you tell your instance variable to refer to the given x, so when you change data in one of these variables, that changes also affect the second variable.
And in the second case you create a copy of an object, so your instance variable and variable you pass to constructor will need independent from each other in your further code.
This will not work since you got an ambiguity issue as both constructors receive the same type of parameters. So when you try to create an instance :
StackOverflow instance = new StackOverflow(new int[]{});
There is no way to know which constructor should be called.
You need to decide which behavior is good for you.
I would recommend using the second constructor and create a setter method if you want to set the array from an initialized one :
public class StackOverFlow {
private int[] x; // instance variable
StackOverFlow(int[] x) { // conctructor
this.x = new int[x.length];
for(int k=0 ; k < x.length; k++) {
this.x[k]=x[k];
}
}
public void setTheArray(int[] x) {
this.x = x;
}
}
Related
public class Test {
public int [] x;
public Test(int N)
{
int[] x = new int [N];
for (int i=0;i<x.length;i++)
{
x[i]=i;
StdOut.println(x[i]);
}
}
public static void main(String[] args) {
String path = "/Users/alekscooper/Desktop/test.txt";
In reader = new In(path);
int size=reader.readInt();
StdOut.println("Size = "+size);
Test N = new Test(size);
StdOut.println(N.x[3]);
}
/* ADD YOUR CODE HERE */
}
Hello guys. I'm learning Java through reading Robert Sedgwick's book on algorithms and I'm using his libraries such as StdOut, for example. But the question is about Java in general. I don't understand why Java here throws a NullPointerException. I do know what that means in general, but I don't know why it is here because here's what I think I'm doing:
read an integer number from the file - the size of the array
in the class Test. In my test example size=10, so no out-of-bound type of thing happens.
print it.
create the object N of type Test.
In this object I think I create an array of size that I have just
read from the file. For fun I initialize it from 0 to size-1 and
print it. So far so good.
and here where it all begins. Since my class is public and I've run
the constructor I think I have the object N which as an attribute
has the array x with size elements. However, when I'm trying
to address x, for example,
StdOut.println(N.x[3]);
Java throws NullPointerException.
Why so? Please help and thank you very much for your time.
what you did is called shadowing you shadowed your field x with local variable x. so all you need to do is avoiding this:
int[] x = new int [N]; is wrong, if you want your field to initialize instead of a local variable then you could do something like : x = new int [N]; for more information read this
change the first line in constructor from
int[] x = new int [N];
to
x = new int [N];
it should work...
Actually in constructor when you say int[] x, it is creating one more local variable instead setting data to public variable x... if you remove int[] from first line of constructor then it initizes the public variable & you will be able to print them in main() method
Inside public Test(int n):
Change
int[] x = new int [N]; // Creating a local int array x
to
x = new int [N]; // Assigning it to x
Everyone has given the code that would work. But the reason is something called as variable scoping. When you create a variable (by saying int[] x, you are declaring x as an integer array and by saying x = new int[4] you are assigning a new array to x). If you use the same variable name x everywhere and keep assigning things to it, it'll be the same across your class.
But, if you declare int[] x one more time - then you are creating one more variable with the name x - now this can result in duplicate variable error or if you're declaring in a narrower 'scope', you will be overriding your previous declaration of x.
Please read about java variable scopes to understand how scoping works.
int size=reader.readInt(); // size < 3
StdOut.println(N.x[3]); // length of x[] less than 3, so x[3] case NullPointException
I got this code:
public static ArrayList<Integer> MakeSequence(int N){
ArrayList<Integer> x = new ArrayList<Integer>();
if (N<1) {
return x; // need a null display value?
}
else {
for (int j=N;j>=1;j--) {
for (int i=1;i<=j;i++) {
x.add(Integer.valueOf(j));
}
}
return x;
}
}
I am trying to call it from the main method just like this:
System.out.println(MakeSequence (int N));
but I get an error...
Any recommendations? Much appreciated, thanks!
System.out.println(MakeSequence (int N));
should be
int N = 5; // or whatever value you wish
System.out.println(MakeSequence (N));
Just pass a variable of the correct type. You don't say that it is an int again;
You define the method as follow MakeSequence (int N), this means that method expects one parameter, of type int, and it'll be called N when use inside the method.
So when you call the method, you need to pass an int like :
MakeSequence(5);
// or
int value = 5;
MakeSequence(value);
Then put all of this in a print or use the result in a variable
System.out.println(MakeSequence(5));
//or
List<Integer> res = MakeSequence(5);
System.out.println(res);
All of this code, to call the method, should be in antoher method, like the main one
Change x.add(Integer.valueOf(j)); to x.add(j); as j is already an int
to follow Java naming conventions : packages, attributes, variables, parameters, method have to start in lowerCase, while class, interface should start in UpperCase
The first issue is I think that N should be some int value not defining the variable in the method call. Like
int N = 20;
ClassName.MakeSequence(N);
The other issue you will face. As System.out.println() only prints string values and you are passing the ArrayList object to it, so use it like this System.out.println(ClassName.MakeSequence(N).toString())
Here is my code... I am a beginner and appreciate any feed back. My problem I am trying to solve is to print the pascal triangle up to the user imputed row.
public class Pascal111 {
int max;
int r,c;
public int pascal(int maxm){
max=maxm;
for(int r=0; r<max; r++){
for (int c=0; c<r; c++){
populate();}
}
return max;
}
public void populate(){
int[][] array=new int[max][max];
if (r==0){
array[0][0]=1;
}
else if(c==0){
array[0][0]=1;
}
else if(c==r){
array[r][c]=1;;
}
else
array[r][c]=(array[r-1]+array[c-1]+array[r-1]+array[c]);
}
}
I get the following error....
Error: bad operand types for binary operator '+'
first type: int[]
second type: int[]
array[r][c]=(array[r-1]+array[c-1]+array[r-1]+array[c]);
is wrong.
array is a 2-D array, thus array[X] represents a complete row (1-D array). You just can't do binary operation on 1-D arrays and put it on a single element array[r][c].
Instead replace it with
array[r][c]=(array[r-1][c-1]+array[r-1][c]);
Although I haven't looked at this closely, one mistake stands out: you have two different variables named r and two different variables named c.
Here's the relevant parts of your code:
public class Pascal111 {
int r,c; // (A)
public int pascal(int maxm) {
for (int r=0; r<max; r++){ // (B)
for (int c=0; c<r; c++){ // (B)
populate();
}
}
return max;
}
public void populate() {
if (r==0) {
... more code that accesses r and c
}
}
The declaration at (A) declares instance variables, because the declaration isn't inside a method. This means that whenever you create a Pascal111 object, this object will have fields named r and c. They are initialized to 0.
The declarations at (B), since they have int keywords on them, declare new variables. These variables are local to the pascal method, which means they can be accessed only inside that method. (Actually, they can be accessed only inside the for loops.) These variables have no connection to the instance variables. They are totally separate. As you increment these local r and c variables, the instance variables remain unchanged. That is, they are still 0.
The populate method can't access local variables declared in pascal. So when populate refers to r and c, they are referring to the instance variables. These are not the variables that get incremented in the loop, but rather the instance variables that remain 0.
One way to fix this would be to remove the int on the declarations in (B); that would cause pascal to increment the instance variables, and then populate would use those. However, that is the wrong approach.
The best way to fix these is not to use the instance variables to communicate between pascal and populate--but rather, to use parameters. That is:
for (int r=0; r<max; r++){ // (B)
for (int c=0; c<r; c++){ // (B)
populate(r, c);
}
}
and later:
public void populate(int r, int c) {
Then, when populate refers to r and c, it will refer to the parameters, which are in essence local variables. The parameters will be the r and c from pascal. (But you don't have to use the same names for the pascal variables and the populate parameters.) After you do this, you'll find that the instance variables are no longer needed at all. It's always, or almost always, wrong to have instance variables used as loop indexes anyway.
A similar error: You have array as a local variable inside populate. This means that you're creating a brand new array every time you call it to set up one array element. Then, when populate returns, array can no longer be accessed, so whatever work you've done is lost.
public class Test {
public int [] x;
public Test(int N)
{
int[] x = new int [N];
for (int i=0;i<x.length;i++)
{
x[i]=i;
StdOut.println(x[i]);
}
}
public static void main(String[] args) {
String path = "/Users/alekscooper/Desktop/test.txt";
In reader = new In(path);
int size=reader.readInt();
StdOut.println("Size = "+size);
Test N = new Test(size);
StdOut.println(N.x[3]);
}
/* ADD YOUR CODE HERE */
}
Hello guys. I'm learning Java through reading Robert Sedgwick's book on algorithms and I'm using his libraries such as StdOut, for example. But the question is about Java in general. I don't understand why Java here throws a NullPointerException. I do know what that means in general, but I don't know why it is here because here's what I think I'm doing:
read an integer number from the file - the size of the array
in the class Test. In my test example size=10, so no out-of-bound type of thing happens.
print it.
create the object N of type Test.
In this object I think I create an array of size that I have just
read from the file. For fun I initialize it from 0 to size-1 and
print it. So far so good.
and here where it all begins. Since my class is public and I've run
the constructor I think I have the object N which as an attribute
has the array x with size elements. However, when I'm trying
to address x, for example,
StdOut.println(N.x[3]);
Java throws NullPointerException.
Why so? Please help and thank you very much for your time.
what you did is called shadowing you shadowed your field x with local variable x. so all you need to do is avoiding this:
int[] x = new int [N]; is wrong, if you want your field to initialize instead of a local variable then you could do something like : x = new int [N]; for more information read this
change the first line in constructor from
int[] x = new int [N];
to
x = new int [N];
it should work...
Actually in constructor when you say int[] x, it is creating one more local variable instead setting data to public variable x... if you remove int[] from first line of constructor then it initizes the public variable & you will be able to print them in main() method
Inside public Test(int n):
Change
int[] x = new int [N]; // Creating a local int array x
to
x = new int [N]; // Assigning it to x
Everyone has given the code that would work. But the reason is something called as variable scoping. When you create a variable (by saying int[] x, you are declaring x as an integer array and by saying x = new int[4] you are assigning a new array to x). If you use the same variable name x everywhere and keep assigning things to it, it'll be the same across your class.
But, if you declare int[] x one more time - then you are creating one more variable with the name x - now this can result in duplicate variable error or if you're declaring in a narrower 'scope', you will be overriding your previous declaration of x.
Please read about java variable scopes to understand how scoping works.
int size=reader.readInt(); // size < 3
StdOut.println(N.x[3]); // length of x[] less than 3, so x[3] case NullPointException
public class foo {
private int a[];
private int b;
public foo(){
a = new int[] {1,2};
b= 3;
}
public int[] getA(){
return this.a;
}
public int getB(){
return this.b;
}
I noticed that it's possible to change a value of A by accessing the object like this:
foo f = new foo();
f.getA()[0] = 5; // f.a[0] changes to 5
but it isn't possible to do something like:
f.getB = 5; // gives error
f.getA() = new int[]{2,3}; //gives error
can someone explain me how this works, and how to prevent the user from changing the value of an array cell?
Thanks in advance.
In Java, array is a reference type, which means that the value of an array expression is a reference to the actual array.
The return value of getA() is, therefore, a reference to the private array inside your object. This breaks encapsulation: you give access to your object's internals.
You can avoid this by either returning a reference to a copy of your internal array, or by providing a different API which only returns individual elements, say a method getA(int index).
f.get(A) returns a reference to an array. You can access that array the way you access any array, and assign values to its elements with f.get(A)[i]=... (though it makes more sense to store the returned array in a variable, which would let you access that array multiple times, without having to call f.get(A) each time).
You can't, however, assign anything f.get(A) via f.get(A)=.., since a method call is not a valid left side of an assignment operator. For all you know, a call to f.get(A) may generate a new array that is not referred to by a member of the foo class, so assigning f.get(A)= new int[5]; would make no sense, since there would be no variable in which to store the new array.
The same explanation applies to f.getB() = 5;.
Instead of giving away the array, to allow the caller to do what they like with it you can use an indexed getter
public int getA(int n){
return this.a[n];
}
public void setA(int n, int x) {
this.a[n] = x;
}
Now, the caller has no access to the array and cannot change it without you knowing.