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;
}
}
Related
I'm trying to write a function checking if 2 arrays are equal.
public class DynamicArray {
private int size; // stores the number of “occupied” elements in the array
private int[] array;
...
boolean equals(DynamicArray obj) {
boolean keepChecking = true;
int objSize = 1;
for (int i = 0; i < obj.length; i++) {
if (obj[i] == 0 && keepChecking) {
keepChecking = false;
objSize = obj[i];
}
}
if (size != objSize)
return false;
for (int i = 0; i < size; i++) {
if (array [i] != obj [i]) {
return false;
}
}
return true;
}
}
The thing is that array might be partially filled array, not filled elements will be just zeros. So, to check if 2 arrays are equal, first, I find the size of the occupied array and then I do all the checkings.
So, every time I'm trying to get the value of obj[i] or obj.length it keeps showing the error "array required, but DynamicArray found." for obj[i] and "cannot find symbol \n symbol: variable length \n location: variable obj of type DynamicArray" which I don't understand because the other array is also DynamicArray type
public class ArrayDemo {
public static void main(String[] args) {
DynamicArray ar1 = new DynamicArray(1);
DynamicArray ar2 = new DynamicArray(1);
System.out.println("equals() is " + ar1.equals(ar2));
}
}
Your parameter obj in the equals method is not an array but an instance of DynamicArray. Therefore you cannot access the values with the [] on the identifier obj. You need to rewrite that method. You also need to include methods for setting and getting the elements of the array in your DynamicArray object. For example:
val = ar1.get(0);
and
ar1.set(0, value);
So this means your Dynamic array needs the following two methods (I am assuming the values of your array are ints, but this could be anything). I'll let you figure out what goes in them as I see you must be learning the language.
public void set(int index, int value){
}
public int get(int index){
}
That way you can then use your methods in your rewritten equals function to access the elements of the array.
Another tip. You would be better sorting both arrays. Compare the first element or each, then the next, and then the next until such time you find a mismatch. At that point you can return false. If you find no mismatch return true.
The thing is , DynamicArray is not an array, its a class, you have to define a length function of it.you can just call obj.length wich is DynamicArray class which has no method length
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);
}
}
}
Im doing a bit of java home work and I seem to be having a small problem. The problem im having is the variable that Im trying to reference is showing that it is not initialized. However, I declared the variable earlier in the method and then had it initialized in a loop. When i try to access the variable when i make the charCount call a few lines later in the same method, the compiler complains that the variable still needs to be initialized. Can someone explain why this isnt working as i think it should.
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class test {
public int charCountHelper(File handle, Character x) throws IOException {
int count = 0;
String data;
int index;
Character[] contents;
Scanner inputFile = new Scanner(handle);
while(inputFile.hasNext()){
data=inputFile.nextLine();
index = data.length()-1;
for(int i = 0; i< data.length(); i++){
contents = new Character[data.length()] ;
contents[i] = data.charAt(i);
}
count += charCount(contents,x,index);
}
inputFile.close();
return count;
}
public int charCount(Character[] content, Character x, int index) {
if(index < 0){
return 0; // this value represents the character count if the program reaches the beginning of the array and has not found a match.
}
if (content[index].equals(x)) {
return 1 + charCount(content, x, index - 1);
}
return charCount(content, x, index - 1); // this is the value that gets returned to the original calling method.
}
}
In your code, contents will not be initialized if data.length() is equal to 0. Initializing contents in the loop is in any case not correct, because if you do it that way, it will only contain one character assigned during the latest initialization of the loop. Simply move the line initializing contents above the loop.
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;
}
}
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
//...
}