Java is not recognizing an object created as an array [duplicate] - java

This question already has answers here:
Accessing arrays with methods
(4 answers)
Closed 8 years ago.
I am creating a simple mechanical computer emulator, with virtual counters and punch cards, but I keep getting errors in java.
It creates counters as an array of objects like this:
private static void createcounters(int counternums, int digits,
int[] countervals){
for (int i=0; i<counternums; i++){
try {
if (digits < 1){
System.out.println("Invalid number of digits, reverting to 1 digit");
digits = 1;
}
Counter[] counter = null;
counter[i] = new Counter(digits, countervals[i]);
} catch (Exception ex) {
}
}
}
The object is referenced at a different point in a program to read values and put those in a integer array:
public int[] getcounters(){
int[] countervals = null;
for (int i=0; i<counternums; i++){
countervals[i] = counter[i].ReturnVal;
}
return countervals;
}
Java gives this error on compiliation:
Exception in thread "main" java.lang.RuntimeException: Uncompilable source code - cannot find symbol
symbol: variable counter
location: class mechanicalcomputeremulator.Computer
at mechanicalcomputeremulator.Computer.getcounters(Computer.java:49)
at mechanicalcomputeremulator.MechanicalComputerEmulator.main(MechanicalComputerEmulator.java:20)
Java Result: 1
If I reference the counter in the method that the objects are created, the error doesn't appear.

You've got at least four problems:
You're declaring the counter variable as a local variable inside your method. I suspect you meant to declare a field somewhere - or return a reference from the method, and assign it to an instance variable there.
You're initializing the variable to null and then immediately trying to dereference it. How do you expect that to work?
You're declaring a different variable for each iteration of the loop. I strongly suspect you mean to declare one variable and populate the same array in all iterations.
You're catching Exception and just ignoring it. Never do that. (Ideally don't do either part of it.)
So sample better code:
private static void createCounters(int counterNums,
int digits,
int[] counterVals) {
// Moved out of the loop, as it's pointless there.
if (digits < 1) {
// TODO: Throw an exception instead?
System.out.println("Invalid number of digits, reverting to 1 digit");
digits = 1;
}
counter = new Counter[counterNums];
for (int i=0; i < counterNums; i++) {
counter[i] = new Counter(digits, counterVals[i]);
}
}
Or:
private static Counter[] createCounters(int counterNums,
int digits,
int[] countervals) {
if (digits < 1) {
// TODO: Throw an exception instead?
System.out.println("Invalid number of digits, reverting to 1 digit");
digits = 1;
}
Counter[] counter = new int[counterNums];
for (int i=0; i < counterNums; i++) {
counter[i] = new Counter(digits, counterBals[i]);
}
return counter;
}
Note that if counterNums is the same as the length of counterVals, you can remove that parameter and just use counterVals.length.

Counter[] counter in createCounters is a method-scoped variable. It will not be available in a different method. If you want to make it available to all methods in your class then it needs to be a field.
However, you need to be aware you are using static on the createcounters method, so you can't access an instance field unless you remove the static keyword on the method.
You also can't do Counter[] counter = null; and then assign values to it, you need to do Counter[] counter = new Counter[size];. I suspect you also want an expandable array, so should use an ArrayList instead.
public class MyClass {
private Counter[] counter = new Counter[10]; // arbitrary fixed size array
private /*static*/ void createcounters(int counternums, int digits,
int[] countervals){
...
counter[i] = new Counter(digits, countervals[i]);
}
public int[] getcounters(){
int[] countervals = null;
for (int i=0; i<counternums; i++){
countervals[i] = counter[i].ReturnVal;
}
return countervals;
}
}

Related

Calling method from another class that's an array

I am calling a method from another class. The method contains an integer array. I am trying to stay away from inputting the index manually.
I am trying to search for numbers within a range.
example:
ArrayList: {1,5}, {5,10}, {10,15}
Input: enter 3
Process: search for number within range
output: 1,5
The driver class is storing the objects from the main class called Numbers into ArrayList. The main class have an accessor call getNumbers. getNumbers contains an integer array with 2 elements. The driver is calling getNumbers to validate the entry that users input.
The code below works but I'm told it's consider bad coding to code entering the indexes. I want to know how to output the array from getNumber method without knowing the array length of getNumber?
example of what I have:
for(int i = 0; i < example.size(); i++)
//number is the integer that is inputted.
if(example.get(i).getNumbers()[1] > number &&
example.get(i).getNumbers()[0] <= numbers)
System.out.println(example.get(i));
Should I add another for loop?
example of what I am thinking of:
for(int i = 0; i < example.size(); i++)
for(int j = 0; j < example.get(i).getNumbers.length; j++){
if(example.get(i).getNumbers()[j] > number &&
example.get(i).getNumbers()[j] <= numbers)
System.out.println(example.get(i));
}
}
Edit: Changed how I worded some things and fixed the code of what I think I should do.
The code below works but I'm told it's consider bad coding to code
entering the indexes. I want to know how to output the array from
getNumber method without knowing the array length of getNumber ?
If you don't want to do the validations with array indexes for your first element and second element in the array, then you can solve the problem by modifying your Numbers class as shown below:
(1) Define two int variable members (currently you have only one)
(2) Add a method isInLimits(int input) to validate the range
(3) Override toString() which can be used to print the object as String
Numbers class (modified):
public static class Numbers {
private int firstElement;
private int secondElement;
public int getFirstElement() {
return firstElement;
}
public void setFirstElement(int firstElement) {
this.firstElement = firstElement;
}
public int getSecondElement() {
return secondElement;
}
public void setSecondElement(int secondElement) {
this.secondElement = secondElement;
}
//checks the input is in the range of this object elements
public boolean isInLimits(int input) {
if(input >= firstElement && input < secondElement) {
return true;
} else {
return false;
}
}
#Override
public String toString() {
return "{"+firstElement+","+secondElement+"}";
}
}
Usage of Numbers Class:
public static void main(String[] args) {
int userInput = 10; //get it from user
List<Numbers> example = new ArrayList<>();
//Add Numbers objects to example list
for(int i=0;i< example.size();i++) {
Number numberTemp = example.get(i);
//call Numbers object's isInLimits
if(numberTemp.isInLimits(userInput)) {
System.out.println(numberTemp);
}
}
}

variable index might not have been initialized issue [duplicate]

This question already has answers here:
Variable might not have been initialized error
(12 answers)
Closed 6 years ago.
So I'm taking AP Computer Science A and I need some help I'm on Activity 28 and I have this question:
The removeExtension method is designed to input a name or 3-digit extension number (presented in the form of a String), and remove from the extensions array the first entry it finds that matches either the name or the extension (or both). If such a removal takes place, the size of the extensions array is reduced by 1.
As in Activity 27.1, a match should be registered when comparing names if the only difference is in the use of uppercase or lowercase letters. So "PETER" and "Peter" should match, while "Peter" and "Pete" should not.
Complete the definition of the removeExtension method:
public class MainClass{
public static PhoneExtension[] extensions = new PhoneExtension[]{
new PhoneExtension("Christine", "763"),
new PhoneExtension("Janice", "464"),
new PhoneExtension("Jon", "564"),
new PhoneExtension("Peter", "760"),
new PhoneExtension("Nicholas", "564"),
new PhoneExtension("Michael", "465"),
new PhoneExtension("Ryan", "564"),
new PhoneExtension("Pamela", "467"),
new PhoneExtension("Janice", "999"),
new PhoneExtension("Christine", "763")
};
public static void printDirectory(){
for (PhoneExtension ext : extensions)
System.out.println(ext);
}
public static void removeExtension(String t){
//My code starts here.
PhoneExtension[] temp = new PhoneExtension[extensions.length - 1];
int index;
for (int i = 0; i < extensions.length - 1; i++){
if (t.toLowerCase().equals(extensions[i].getName().toLowerCase()) || t.equals(extensions[i].getExtension())){
index = i;
continue;
}
}
for (int i = 0; i < index; i++){
temp[i] = extensions[i];
}
for (int i = index; i < temp.length - 1; i++){
temp[i + 1] = extensions[i];
}
extensions = temp;
//And ends here.
}
public static void main(String[] args){
removeExtension( "Peter" );
printDirectory();
}
}
This throws this error:
MainClass.java:75: error: variable index might not have been initialized
for (int i = 0; i < index; i++){
^
A few things to note are: the PhoneExtension class isn't shown but it has a getName and getExtension method that return it's name or extension. It's constructor looks like: PhoneExtension(String name, String extension). I don't know why we aren't using ArrayLists for this, seems like it could save some trouble but I could be missing something that is keeping us from using them...
You need to initialize the local variable index. If i < extensions.length - 1 is never true, then index won't be initialized and that is why the compiler complains.
do this: int index = 0.

JAVA Pass by reference error in method

I was trying to perform sorting of integers in an array and it worked fine.
But when i try to modify the program by including a "pass by reference" concept via a method, it is throwing error "cannot find symbol".
I am new to JAVA and learning by my own, Please help me with what I am doing wrong here.
import java.util.*;
import java.io.*;
public class Sort {
public static void main(String[] args) {
Sort obj = new Sort();
Scanner in = new Scanner(System.in);
int i, p, k, arr[];
arr = new int[10];
System.out.println("Enter the numbers for sorting \n");
for (i = 0; i < 5; i++) {
arr[i] = in.nextInt();
}
for (i = 0; i < 5; i++) {
for (p = 0; p < 5; p++) {
if (arr[i] < arr[p]) {
/*
* moving the below block for swapping to a new method. k =
* arr[i]; arr[i]= arr[p]; arr[p]= k;
*/
obj.swap(obj);
}
}
}
System.out.println("\n");
for (i = 0; i < 5; i++)
System.out.println(arr[i]);
}
public void swap(Sort m) {
m.k = m.arr[i];
m.arr[i] = m.arr[p];
m.arr[p] = m.k;
}
}
The error I am getting is :
"Sort.java:44: error: cannot find symbol
m.k = m.arr[i];
^
"
Similarly 10 such errors for other variables as well.
You are trying to use index variables (i and p) that don't exist in the context you are trying to use them (inside swap() method body) as well as members of Sort (k and arr) which don't exist. The scope of all these, you have limited to the method body of main():-
public void swap(Sort m) {
m.k = m.arr[i]; //No 'i' in swap(). No 'k' or 'arr' in 'm'(an instance of 'Sort')
m.arr[i] = m.arr[p]; //No 'p' in swap()
m.arr[p] = m.k;
}
Short-term Solution
Change your swap() method to
//Now accepting in i and p
public void swap(Sort m, int i, int p) {
m.k = m.arr[i];
m.arr[i] = m.arr[p];
m.arr[p] = m.k;
}
then call it like this
obj.swap(obj, i, p); //pass in i and p
and move your Sort variables to be accessible members of Sort
public class Sort {
public static int k; //now accessible with m.k
public static int[] arr = new int[10]; //now accessible with m.arr
...
}
Lastly, is it intentional that your array is 10 long but you only fill it with 5 numbers?
Pass-by-Reference
There is no "pass-by-reference" in Java. Everything is passed by value. The confusing thing is that what is passed by value is technically a reference to the object, meaning you get strange effects like you can edit the object but not reassign it.
Solution: move the stuff back from the swap method to where it was.
Alternatively, provide the necessary values as parameters to swap.

Cannot find symbol in for loop

I am getting the error now that BookCollection.java:67: error: incompatible types
collection[lastElement++] = b;
Also am not sure if my constructor is set up correctly? The directions were:
Constructor:
Given a parameter specifying the limit on the collection size, an empty book collection is created using the given parameter. The parameter should not exceed the preset maximum size 200.
Am I initializing my variables correctly then? An answer below helped me change my code, but although I do not get errors within my constructor, I feel as though it may not be correct according to the directions....
I'll paste the couple chunks of my code that pertain to the question.
public class BookCollection{
//data fields, need complete
private int limit = 200;
//Array of type book
private int Book[];
//actual size of collection, initialized to zero. Must never exceed limit
private int collection[];
private int lastElement;
//Constructor
public BookCollection(int l, int c[], int le,int b[]){
Book = b;
collection = c;
limit = l;
lastElement = le;
int lastElement = 0;
if(limit <= 200){
Book[] collection = new Book[limit];
} else{
throw new UnsupportedOperationException("CannotExceedLimit");
}
}
ANNDDDD where I am getting the error:
public void addBook(int b[], int c[]) {
Book = b;
collection = c;
if (lastElement == collection.length) {
throw new UnsupportedOperationException("CorrectionFull");
}
for (int i = 0 ; i != lastElement ; i++) {
if(b.equals(collection[i])) {
throw new UnsupportedOperationException("DuplicateBook");
}
}
collection[lastElement++] = b;
}
You have not declared i as an integer in your for loop. So add the declaration with initialization. Replace this
for(i=0; i<collection.length; i++){
with
for(int i=0; i<collection.length; i++){
This statement
BookCollection[] collection = new BookCollection[limit]; //initialize array of 200
declares a local array. It gets destroyed as soon as you leave the constructor.
The collection that stays around is this one:
private int collection[];
It consists of ints, so when you try to do this
collection[i].add(b);
the compiler correctly complains that int does not have a method called add.
Good chances are, even declaring the collection as
private Book[] collection;
and initializing it in the constructor as
collection = new Book[limit];
is not going to help, though: unlike collections, Java arrays do not let you change their size dynamically, so you need to store an index of the last element of the collection[] array that has been set.
This leads to understanding that you need a loop for finding duplicates, and noting else: define an element int lastElement, set it to zero in the constructor, and rewrite the addBook method as follows:
public void addBook(Book b) {
if (lastElement == collection.length) {
throw new UnsupportedOperationException("CorrectionFull");
}
for (int i = 0 ; i != lastElement ; i++) {
if(b.equals(collection[i])) {
throw new UnsupportedOperationException("DuplicateBook");
}
}
collection[lastElement++] = b;
}
You did't declared i as a int type variable, make it as
for(int i=0; i<collection.length; i++){
^here
//...
}

copy array in to another array using a for loop

following are the steps of the program I'm trying to make
catch String using Scanner
pass that String to a method in another class
separate characters of that String in to an array using .toCharArray()
copy contents of that array to another array using a for loop
but this array giving me a null pointer exception. what am i doing wrong? (ignore the class naming i know it's stupid but i have to do it this way because my teacher wants it that way)
main class:
import java.util.Scanner;
public class _01 {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter your name : ");
String name = input.nextLine();
int size = name.length();
_02 process = new _02(size);
process.push(name);
}
}
other class with the array:
public class _02 {
int maxsize;
int top;
char arrayStack[];
public _02(int size) {
maxsize = size;
top = -1;
}
public void push(String letters) {
char temp[]= letters.toCharArray();
for (int c=0;c<temp.length;c++) {
temp[c] = arrayStack[++top];
}
}
}
Your assignment is reversed - you want to assign from temp (right side of assignment) to arrayStack (left side of assignment). Also, you need to initialize arrayStack, e.g. arrayStack = new char[temp.length] - right now it's null.
char arrayStack[]; // this is not initialized.
arrayStack[] = new char[temp.length] // inside the push() method.
Arrays need to be initialized in Java; simply declaring an array yields a field initialized to null. Once you change the class to properly initialize arrayStack, you don't need the maxsize field, since it will be the same as arrayStack.length. You also have your assignment reversed in the push method. Finally, since you have a maximum array size, you might want to avoid throwing an ArrayIndexOutOfBoundsException and instead throw a more semantically meaningful exception, or else simply drop the extra characters or grow the stack (in which case the constructor arg is an initial size). For that, you will need some range checking. Finally, the logic is cleaner if you initialize top to 0 instead of -1 and use top++ instead of ++top (or, better, use the built-in API for copying pieces of an array).
public class _02 {
int top;
char arrayStack[];
public _02(int size) {
arrayStack = new char[size];
top = 0;
}
public void push(String letters) {
char temp[]= letters.toCharArray();
int len = temp.length;
// do some range checking
if (top + len >= arrayStack.length) {
// silently ignore the extra characters
len = arrayStack.length - top;
// an alternative would be to throw a "stack full" exception
// yet another alternative would be to grow the stack
}
// for (int c=0; c<len; c++) {
// arrayStack[top++] = temp[c];
// }
// don't use a loop--use the API!
System.arraycopy(temp, 0, arrayStack, top, len);
top += len;
}
}

Categories