How to get length from array as a cass memeber? - java

I have a class that has some arrays as members. In some member functions i want to then iterate over said arrays. But when i try to get the length of the array i see the error non static variable cannot be referenced from a static context.
I have the line for(int i = 0; i < this.blue; i++){} and the array is private int[][] blue;
For example:
public class M{
private int[][] arr;
public static void func(){
for(int i = 0; i < this.arr.length; i++){
// ^^^^ compiler does not like this
}
}
}
I understand that i am not looking at an instance of the class, so the value could be anything, but then how will i ever be able to preform such basic operations if i have to know everything before hand?
I have tried to create another member that holds the dimensions, but that leads to the same issue.

public class M{
private int[][] arr;
public void func(){
for(int i = 0; i < this.arr.length; i++){
// ^^^^ compiler does not like this
}
}
}
This removes the error. That is removing static from func(). At some point I learned to write it and then stopped questioning it. Thanks for the input in the comments.

Related

Java class does not recognize indexing

I made a Matrix class in JAVA that consists of a 2D int array with row and column variables. The constructor of the class generates a Matrix of dimensions n x m and I also implemented two methods that print the values of the Matrix and its transpose (getMatrixValues and getTransposedValues).
However, I would like to make a function that takes as input a matrix and returns its transpose, but since this class is not an array I cannot iterate over it using AT[j][i] = A[i][j], if I understand the exception correctly that IntelliJ is returning me ("java: array required, but Matrix found").
Obviously, I could simply use an int[][] class to begin with instead of defining a new class, but since I am new to JAVA and object-oriented programming in general I wondered whether there is not another possibility without discarding my Matrix class?
Here is my code:
import java.util.Random;
import java.util.Arrays;
public class Matrix {
private int n; // rows
private int m; // cols
private int[][] A; // matrix
public static void main(String[] args){
Matrix A = new Matrix(4,4);
A.getMatrixValues();
System.out.println("\n");
A.getTransposedValues();
Matrix AT = transposeMatrix(A);
}
// constructor (randomly generates matrix)
public Matrix(int rows, int cols){
n = rows;
m = cols;
A = new int[rows][cols];
Random r = new Random();
// r.setSeed(1);
for(int i = 0; i < rows; i++)
{
for(int j = 0; j < cols ; j++)
{
A[i][j] = r.nextInt(10);
}
}
}
// print matrix
public void getMatrixValues(){
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
System.out.print(A[i][j]+"\t");
}
System.out.print("\n");
}
}
// print transposed matrix
public void getTransposedValues(){
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
System.out.print(A[j][i]+"\t");
}
System.out.print("\n");
}
}
public static Matrix transposeMatrix(Matrix A){
Matrix AT = new Matrix(A.get_n(), A.get_m());
for(int i = 0; i < A.get_n(); i++)
{
for(int j = 0; j < A.get_m(); j++)
{
AT[j][i] = A[i][j];
}
}
return AT;
}
// getters
public int get_n(){
return n;
}
public int get_m(){
return m;
}
}
Preface
What I have noticed only afterwards was, that when creating the transposed matrix, you actually want to create one with m-rows and n-columns.
That means, you have mixed up m and n in transposeMatrix() when instantiating the new object.
That also means that your code -as it is- only works for square matrices. Just create the object like this: new Matrix(matrix.get_m(), matrix.get_n()).
Note: I re-named your variables; see below in section "Solution".
However, since this is not part of you question, I have not fixed it in the code-snippets below.
Scopes
When in every other method, you are in the lexical scope of the object you are in. This allows you to access its fields (like int[][] A).
But when inside transposeMatrix(Matrix A), you are inside the static scope, meaning, not in the scope of an object.
What adds to the confusion is, that your instance-variable is called A, much like the parameter Matrix A of transposeMatrix(). While you were able to access the 2D-array via A, you now access a Matrix-object via A. That is both because we are not in an object anymore, and because the new local variable overrides the access to the similarly named instance-/static-variable (you would have to use this.A or Matrix.A respectively).
Access modifier
When trying to fix your code, you will stumble upon the restriction of the access modifier you used: private.
private int[][] A will make A (your array) only accessible when referenced from inside your object. But when calling transposeMatrix(), we are in a static-context, meaning, not inside your object anymore.
To fix this, can change the access modifier to allow us to access that field from outside the object. To enable this, you can change the modifier to any other option, with the easiest being to just remove it. However, I suggest you to read more about Access Modifier in the official documentation.
Solution
Let's say we removed private from int[][] A. Will the code work?
No. That's because of the confusion I talked about when explaining scopes. To clear up the confusion, let's rename some variables: (Changed int[][] A to int[][] array, Matrix A to Matrix matrix, Matrix AT to Matrix matrixTransposed)
int[][] array; // <-- Notice the removed access modifier!
// ...
public static Matrix transposeMatrix(Matrix matrix){
Matrix matrixTransposed = new Matrix(matrix.get_n(), matrix.get_m());
for (int i = 0; i < matrix.get_n(); i++) {
for(int j = 0; j < matrix.get_m(); j++) {
matrixTransposed[j][i] = matrix[i][j]; // Won't work!
}
}
}
The code above is still faulty. That is -as we can clearly see now- because we are trying to access a Matrix-object as if it was an array. However, we need to access its instance variable. So, instead of accessing the array the wrong way, we add a .array after every Matrix-object where we try to access its array.
public static Matrix transposeMatrix(Matrix matrix){
Matrix matrixTransposed = new Matrix(matrix.get_n(), matrix.get_m());
for (int i = 0; i < matrix.get_n(); i++) {
for(int j = 0; j < matrix.get_m(); j++) {
matrixTransposed.array[j][i] = matrix.array[i][j]; // NOW we are accessing their arrays respectively
}
}
}
Another solution
With changing the access modifier of the array (like we did above), we enable one to not only override the values of the array, but also to override the array itself.
To restrict one from doing so, we can use "Getters and Setters". They are like a middle-man, allowing us to access the array only indirectly, but with that much control over it as we seem necessary.
We can define them simply creating two new methods (hence its name):
public int get(int i, int j) {
return array[i][j];
}
public void set(int i, int j, int value) {
array[i][j] = value;
}
As you see, we simply forward the request to the "middle-man", which handles it accordingly.
Note: We might encounter a Runtime Exception since we are not checking if the fields at the specified indices actually exist. You might want to add some if-statements before accessing them.
By using the getter and setter, we can modify the code to this:
private int[][] array; // We still want to restrict access to 'array'...
// ...
// ...but still allow accessing them, be it indirectly
public int get(int i, int j) {
return array[i][j];
}
public void set(int i, int j, int value) {
array[i][j] = value;
}
// Now using getter and setter
public static Matrix transposeMatrix(Matrix matrix) {
Matrix matrixTransposed = new Matrix(matrix.get_n(), matrix.get_m);
for (int i = 0; i < matrix.get_n(); i++) {
for (int j = 0; j < matrix.get_m; j++) {
matrixTransposed.set(j, i, matrix.get(i, j));
}
}
}
Sidenote
You should also take a look at naming conventions. They are not critical to make your code function, but make reading and understanding (and thus debugging) it a lot easier.
What I think is also good, is to take a look at a style-guide to see how you can make your code more readible with easy tricks, or just to have a consistent style across your code. I enjoy Google's style-guide for Java, however, there are a lot others as well.
And, you don't have to stick to an existing style-guide, you can have your own style, too! But try to be as consistent as possible. That makes it easier for others and yourself in the future when re-reading your code.

java arrays reverse not understanding the logic

I was trying to use this code I made to reverse a array. I don't understand why I was getting [I#7a84639c as my output in my console.
And for some reason why doesn't this method actually save my reversed array into the array? If i add a print at the bottom of x[i]=c[i]; it shows the array reversed but when i add a call for example karn[0] it shows that my array isn't actually reversed. I want to solve this by staying true to the code i made.
import java.util.Arrays;
public class HelloWorld {
public static void main(String[] args) {
int[]karn={1,2,3};
rev(karn);
System.out.println(karn.toString());
}
public static void rev(int[]x){
int[]c=new int[x.length];
for(int i=x.length-1;i>-1;i--){
c[i]=x[i];
x[i]=c[i];
}
}
}
in your rev method you are using a local variable for c. So this value will not be transferred over to your main method. You must return your array and assign the value to your old array:
public static int[] rev(int[]x){
//Creates new array this array is different from karn and local to the method.
//nothing outside of this method can see this array.
int[]c=new int[x.length];
for(int i = 0; i < c.length; i++){
//Here is where we are swapping the values by placing the first
//value at the last spot of the array and so on
c[c.length - i - 1] = x[i];
}
//we must return the new array we made and assign it to karn so our
//changes will be saved and seen outside of the method
return c;
}
In main method you must assign the changes of the rev method to karn. You can assign the value and display it like so:
karn = rev(karn);
//for each loop
for(int i : karn)
System.out.println(i);
//traditional for loop
for(int i = 0; i < karn.length; i++)
System.out.println(karn[i]);
Arrays do not have a default toString() method. That is why you are seeing the values of the array as you would like. You need to iterate through the array to display them to the console.
Your initial approach looked almost correct, you can do this in-place or through a copy. I posted a comment showing a copy, so I thought I might expand on in-place. I would start with a simple swap method, like
private static void swap(int[] x, int i, int j) {
if (i != j) {
int t = x[i];
x[i] = x[j];
x[j] = t;
}
}
Then you only need to iterate the first half of the array, swapping each element with the same index (but from the other half). Like,
public static void rev(int[] x) {
for (int i = 0; i < x.length / 2; i++) {
swap(x, i, x.length - i - 1);
}
}
Then you might call it like
public static void main(String[] args) throws IOException {
int[] karn = { 1, 2, 3 };
rev(karn);
System.out.println(Arrays.toString(karn));
}
for an output of
[3, 2, 1]

Array as an attribute in a java class?

I have an assignment which consists of several small tasks:
I have to initilize an array and fill it with a 200/400/800 values (each amount - once).
I have to take the array values and put it in a red black tree, with certain conditions that are translated to methods.
Some more tasks.
I could do it all in the main class, however it seems to me I would be better off start a new class - handleArray.
If I start a class such as:
public class handlyArray{
protected int [] arr = new int[];
}
But if I do that, should I write a "get" and "set" functions to get the array's length?
The problem is that when I make this an error pops up - "Array initilizer expected".
Additional functions I have in the class:
public void fillArray(handleArray arr, int k){
Random rand=new Random();
for (int i = 0; i <k ; i++) {
int value = rand.nextInt(1024);
arr[i]=value;
}
}
- A function that creates Nodes for the redblackTree and inserts them to the tree
Any suggestions for how to build it?
Can I build the class with no attributes at all?
Thanks!
I'm wary of this being homework so I'll give you an overview and let you do the specifics.
Yes you can build a getter and setter in your new class, something like:
public int[] getArray() {
return arr;
}
public void setArray(int[] arr) {
this.arr = arr; //
}
As for getting the length, you don't need a method for it as you can just call the above getter and ask it for the length, e.g.
int arrayLength = handlyArray.getArray().length;
Finally yes you need to set up your array first, if you pass in an initialized array to the setter that will do fine, e.g.
handlyArray.setArray(new int[] {200, 400, 800});
Good luck, feel free to ask if you require further explanation.
You can inisialize the array inside the method like this :
public void fillArray(handlyArray arr, int k) {
Random rand = new Random();
arr.arr = new int[k];//<<---------------------Initialize the array
for (int i = 0; i < k; i++) {
int value = rand.nextInt(1024);
arr.arr[i] = value;// Note to fill the array you have to use arr.arr not just arr
}
}
and the handlyArray should be like this :
public class handlyArray {
protected int[] arr;//<<---------------------Just declare the array
}
to use fillArray method you can use :
a.fillArray(new handlyArray(), length);
I don't think so. I would just do a static method somewhere:
public static int[] randomArray(int size){
Random rand=new Random();
int[] arr = new int[size];
for (int i = 0; i < size ; i++) {
int value = rand.nextInt(1024);
arr[i]=value;
}
return arr;
}
Now, as for the red/black tree, I believe that a TreeSet is implemented with a red/black tree.
You can't set an arrays length. The length of an array has to be set during initialization. You can pass the length of the array in the constructor of your class:
public class HandleArray {
protected int [] arr;
public HandleArray(int length) {
arr = new int[length];
}
}

How to print out an element which has been processed by an function.

Good day everyone, I'm finishing some studycode and I'm stuck at the last step!
That is, to print out an element from an array which has been randomly generated by calling upon a function which does so.
I'm scratching my head here, since the statement must pick out a certain element from the array and then print it out, and I've run it through an visualizer and it does everything correct right up to the end.
So I'm hoping if you guys(and gals) can help me understand a bit better what's going on.
public class randomfylki
{
public static int veljaEitt(int [] a)
{
int x = (int)(Math.random()*10);
return a[x];
}
public static void main(String[] args)
{
int a[] = new int[10];
int i;
for( i = 0; i < 10; i++)
{
a[i] = (int)(Math.random()*100);
}
veljaEitt(a);
System.out.print(a);
}
}
I do hope you'll forgive me for having a bad title, I'm not quite sure on what it should be ._.
instead of
veljaEitt(a);
System.out.print(a);
do this
System.out.print(veljaEitt(a));
Your method returns an int, you can store that into a variable and print the variable:
int result = veljaEitt(a);
System.out.print(result);

Having trouble with an element switch

So I am trying to do an element switch. Basically switch two elements in a 2D array. I am not getting any errors but it just doesn't work out right, and doesn't even print all of the elements. What am I doing wrong. Here is the code.
public class ArrayTheory
{
public static void printArray(int[][]args)
{
for(int i=0;i<args.length; i++)
for(int j=0;j<args.length; j++) {
System.out.print(args[i][j]);
}
System.out.println();
}
public static void arraySwitch(int c1, int c2, int [][]args)
{
for(int i=0;i<args.length; i++)
for(int j=0;j<args.length; j++) {
int temp = args[i][c1];
args[i][c1] = args[i][c2];
args[i][c1] = temp;
}
}
}
And here are the elements
public class TestArray {
public static void main(String[] args){
int[][] test = {{1,2,3,4},
{1,2,3,4},
{1,2,3,4}};
int[][] carData = {{16,2008,4},
{45,2011,4},
{26,2010,7},
{18,2009,8}};
ArrayTheory.arraySwitch(0,2,test);
ArrayTheory.printArray(test);
}
}
Since the array isn't square you you need to index the second dimension with args[0].length or args[i].length if each row doesn't have the same length.
You have a bug in your code in the inner loop of arraySwitch
int temp = args[i][c1];
args[i][c1] = args[i][c2];
args[i][c1] = temp; <<<<<<< bug
That should be
args[i][c2] = temp;
Your question is not very clear. If you are trying to swap two specific elements, then you need four coordinates (a1, a2) and (b1, b2) to address each element. Your code seems to be trying to swap two rows. Your print method looks fine, except your outer loop does not have braces. So your println() will only execute once, after the entire contents of the 2D array have been printed.

Categories