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.
Related
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);
}
}
}
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.
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.
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;
}
}
When i call my TruthTable class & populate it w/inputs, I can't access individual slots in the array when I'm trying to set the inputs of the AND gates?
threeAndGates.java -the class where the error happens
import java.util.Scanner;
public class threeAndGates {
public static void main(String[] args){
LogicGate and1 = new LogicGate(LogicGate.AND);
LogicGate and2 = new LogicGate(LogicGate.AND);
LogicGate and3 = new LogicGate(LogicGate.AND);
System.out.print("What is the number of Inputs? ");
Scanner scan = new Scanner(System.in);
int numOfInputs = scan.nextInt();
System.out.print("What is the number of Outputs? ");
int numOfOutputs = scan.nextInt();
TruthTable Table1 = new TruthTable(numOfInputs,numOfOutputs);
Table1.PopulateTruthTable();
//below is where it is giving me "the type of the expression must be an array type but it resolves to TruthTable"
for(int r = 0; r<(Math.pow(2, numOfInputs)) ; r++ ){
and1.setInput1(Table1[r][0]);
and1.setInput2(Table1[r][1]);
and2.setInput1(Truth1[r][2]);
and2.setInput2(Truth1[r][3]);
and3.setInput1(and1.getOutput());
and3.setInput2(and2.getOutput());
Table1[r][numOfInputs + numOfOutputs] = and3.getOutput();
}
Table1.printTruthTable();
}
}
TruthTable.java
public class TruthTable {
private int numOfInputs;
private boolean[][] table;
public TruthTable(int inputs, int outputs){
this.numOfInputs = inputs;
int rows = (int) Math.pow(2,inputs);
int columns = inputs + outputs;
table = new boolean[rows][columns];
}
public void printTruthTable(){
for(int r = 0 ; r < table.length ; r++){
for(int c = 0; c < table[r].length; c++)
System.out.printf("%-5b ", table[r][c]);
System.out.println();
}
}
public String toString(){
String outStr = new String();
for(int r = 0; r < table.length; r++){
for(int c = 0; c < table[r].length; c++)
outStr += String.format("%-5b ", table[r][c]);
outStr += '\n';
}
return outStr;
}
public boolean[][] PopulateTruthTable(){
String s;
String r ="";
int[] Line = new int[numOfInputs];
boolean bit;
for ( int i= 0; i < Math.pow(2,numOfInputs) ; i++){
int x = numOfInputs - Integer.toBinaryString(i).length();
for(int j = 0; j<x ; j++)
r += "0";
s = r + Integer.toBinaryString(i);
for(int k=0; k<s.length() ;k++){
Line[k] = s.charAt(k)-48;
}
for(int m=0 ; m<numOfInputs ; m++){
if(Line[m]==1) bit = true;
else bit = false;
table[i][m] = bit;
}
r="";
}
return table;
}
}
Your TruthTable class is not an Array. It contains an Array. You could add a get and set method to your TruthTable class:
public boolean getValueAt(int x, int y) {
return this.table[x][y];
}
public void setValueAt(int x, int y, boolean value) {
this.table[x][y] = value;
}
and use that to work with the TruthTable values.
This is unrelated to your problem, but when naming variables in your classes, the general practice is to use lower case. For example you have:
TruthTable Table1 = new TruthTable(numOfInputs,numOfOutputs);
would be better
TruthTable table1 = new TruthTable(numOfInputs,numOfOutputs);
and probably best as
TruthTable truthTable = new TruthTable(numOfInputs,numOfOutputs);
The better and more consistent you name things the easier it will be to read down the road.
Your TruthTable class isn't a mutil-dimensional array; it has a multi-dimensional array field. Therefor, you can not use the following syntax:
tableInstance[x][y]
If you TruthTable's table field was public, or better yet, it had a getter, you could do womthing like this instead...
tableInstance.getTable()[x][y]
Some languages (like C#) also support operator overloading which would allow you define the behaviour of using the [] index operator (or others like +, /, etc.). This would allow you to make the indexing work. Unfortunately, Java doesn't have this feature.
This is more of a comment than an answer but I needed more space.
If your code causes you problems later, may I make a suggestion? Break down populateTruthTable into 2 or 3 methods, putting each loop in it's own well named method because Each method should do exactly one thing
Also you probably shouldn't be accessing the array directly from the main class, instead put all the code from your main classes "for" loop into a method in the TruthTable class and call that method from main because you should Tell an object what to do rather than asking for it's data.
I'm not trying to say you're doing it wrong or anything, you are obviously doing very well, but it's always good to pick up more coding tricks/practices as you go along and you seem like you are at the level where these would come in handy.