This is for homework, and I am becoming a little frustrated with how I can't figure out something so simple.
To simplify my code, I have 3 files right now: one class with an add() method I created among other things, one file that tests it (made by the prof), and one that creates the object (which I won't post, b/c its working). Here's the add() function.
EDIT 2: I'm going to add the method that prints the array, maybe that's the problem?
public class Population {
private Person[] pop = new Person[15];
private int numPop = 0;
public void add(Person c){ // this object is created in another class, it works fine
for(int i = 0; i < pop.length; i++){
if(pop[i] == null) {
pop[i] = c;
numPop++;
} else {}
}
public String listPeople(){
System.out.println("Population with "+numPeople+" people as follows:");
int i = 0;
while (i<numPeople){
System.out.println("A "+pop[i].getAge()+"year old person named "+pop[i].getName());
i++;
//FYI the get methods are working fine and are in another file.
}
return("");
}
Then, I run the program in a test file to ensure it works, which was provided to us. Here's the part that isn't working
public class PopTestProgram{ // FYI the prof created this, I can't change this
public static void main(String[] args){
Population pop = new Population(15);
pop.add(new Person(4, "Bob"));
pop.add(new Person(25, "Kim"));
// then adds 8 more people with different ages and names
// then prints the people
It compiles, but when I run it, it just puts 10 of the last person into the array, then crashes saying there is a problem with the "pop[i] = c;" line. I simply cannot figure out what I need to change here.
I haven't received an email from the prof directly, so I thought I'd ask here.
Edit: Here's what it shows after printing out the last person 10 times. It is showing problems with other methods that I haven't completed yet though...
java.lang.ArrayIndexOutOfBoundsException: -1
at Population.removePerson(Population.java:49)
at PopTestProgram.main(PopTestProgram.java:31)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.drjava.model.compiler.JavacCompiler.runCommand(JavacCompiler.java:272)
In add(Person), you are not stopping when you add an item, so the first item you added is put in all cells in the array, then the rest won't go in at all, since there are no more null cells in array. Break the loop when you find an empty location.
public void add(Person c) {
for(int i = 0; i < pop.length; i++){
if(pop[i] == null) {
pop[i] = c;
numPop++;
break;
}
else {
//.....
}
}
}
Could also just use numPop as the next location in the list, like:
public void add(Person c) {
if (numPop < pop.length) {
pop[numPop++] = c;
}
}
The exception is coming in at Population.removePerson(Population.java:49), which is not related to add method. So I assume removePerson is the method to print the person.
While removing you are calling one extra For loop, make sure your iteration is 10 times only.
The java.lang.ArrayIndexOutOfBoundsException: -1clearly tells the removePerson method is calling the index -1 also (which doesnt exist causing ArrayIndexOufofBoundsException). The removePerson method should start from index 9 to index 0 (or viceversa) [10 iteration in total] and then stop out.
Hope this helps
Related
I am a beginner in Java looking for some help to finish my assignment. Here you have the assignment text :
A Stack of integers is an abstract data type that allows the following operations:
1) memorize integers (input function)
2) print the memorized numbers in the insertion order (print method)
3) reverse the insertion order of the numbers (reverse method)
4) concatenate two stacks (concatenate method)
5) copy the content of the stack to an array (toarray)
Write a java class to implement the abstract data type of integers. The program should work with the main file.
The first thing i did was create a class that contains the methods such as: print, input, reverse, concatenate, copy, etc to store the integers in an array, print them using the print method, reverse the insertion order. No problems here.
My problem comes when i want to concatenate two arrays of integers (input from the main) using a method in the class. Instead, the program outputs some numbers + the "java.lang.NullPointerException" error which i think i understand reason for.
Here you can see the stack class:
import java.util.Arrays;
public class Repo {
private static int SIZE;
private int [] Repo ;
private int [] Repo2;
private int top;
Repo () {
Repo = new int [SIZE];
}
Repo (int l) {
Repo = new int [l];
}
public void input (int in) {
Repo[top] = in;
top++;
}
public void stampa () { //print
for(top = 0; top < Repo.length; top++ ) {
if(Repo[top]!=0) {
System.out.print(Repo[top] + " ");
}
}
System.out.println();
}
public void gira() { //Invert
for(top=0; top < Repo.length/2; top++) {
int reverse = Repo[top];
Repo[top] = Repo[Repo.length -top -1];
Repo[Repo.length -top -1] = reverse;
}
}
public void appendi(Repo s) { //Append
int aLen = Repo.length;
int bLen = Repo2.length;
int[] result = new int[aLen + bLen];
System.arraycopy(Repo, 0, result, 0, aLen);
System.arraycopy(Repo2, 0, result, aLen, bLen);
}
public void toarray () {
int [] Repo2 = Repo.clone();
}
}
Here you have the main:
public class TestRepo {
// gioca con i repositori di interi
public static void main(String[] args) {
// il risultato deve essere:
//
// 42 43 44 45
// 1 2 3 45 44 43 42
Repo r = new Repo(10);
// r potra' contenere un massimo di 10 elementi
Repo s = new Repo(20);
r.input(42);
r.input(43);
r.input(44);
r.input(45);
r.stampa();
s.input (1);
s.input (2);
s.input (3);
s.gira();
r.appendi(s);
r.gira();
r.stampa();
}
}
As you can see in the main, the numbers were entered using two different references r.input() & s.input().
In order to get the desired output i used the clone method to create a copy of the first array, merge it with a second one and then print it.
The output should be:
42 43 44 45
1 2 3 45 44 43 42
The output i get is:
42 43 44 45
Exception in thread "main" java.lang.NullPointerException
at Repo.appendi(Repo.java:46)
at TestRepo.main(TestRepo.java:32)
I think the cause of the error is that i am not indicating the right reference in the "append" method, but i am not sure. There might be other errors i may not be aware of in my code.
Any help will be appreciated
Thank you very much
As #WJS pointed out, you never initialised Repo2 and there for it's value is null.
therefore: int bLen = Repo2.length; throws an NullPointerException.
I think what you want to do is bLen = s.length as you probably want to size of this Repo plus the size of the repo you want to append, which is s, not Repo2.
This is only regarding your error.
I think your whole implementation is somewhat off.
I would advice you to do some reading on what exactly stacks are, just google it.
Now you work with arrays of integers, but I think you should use Stack instead.
Why would you otherwise have a function called toArray, when your stack implemenation is already an array? Doesn't make sense. I could be wrong tough...
And for your print function I do not see why 0 should not be printed.
Nice job on the inverse though
When performing your changes, you should work only with your stack implementation and nothing else. Here are some pointers.
Repo should only have one array which acts as a stack.
Repo should have a method that prints itself and nothing else.
Repo should be able to reverse itself. That can be done in place, but if you use another array it shouldn't be visible outside of your class. If I were going to do this I would return a reversed version of the stack, rather than mutate one.
The append method should take to stacks. It should create an instance of the stack, populate that instance from the two passed stacks, and return it as a new instance of stack.
A toArray method simply returns a copy of the array backing your stack. Don't just return the array object because mutating that array would also mutate the stack.
The above is how I might approach this. If I said anything that was in conflict with what your instructor wanted or expected, then your instructor's word certainly takes precedence.
Here is an example of how I would handle the append operation. It works as follows:
returns a new stack with the supplied stack appended to the calling stack.
updates the index of the returned stack to point to the next slot.
For an existing Stack one and Stack two to append two to one would be called like this.
Stack appended = one.append(two);
Here is how it might be implemented (has not been thoroughly tested).
data is the internal array that backs the stack
index is the internal pointer that keeps track of elements.
// append stack to this stack
public Stack append(Stack stack) {
// create a new stack to return
Stack retStack = new Stack();
// copy the data from the current stack to the new, ensuring
// space for both
retStack.data = Arrays.copyOf(data, index + stack.index);
System.arraycopy(stack.data, 0, retStack.data, index,
stack.index);
// update the returned stack's index.
retStack.index = index + stack.index;
// return the stack.
return retStack;
}
This is only one possibility. The overall idea is to return a new stack to house any modifications to an existing stack without changing the existing stack. It all depends on how much flexibility you are permitted with your solution and the requirements of your instructor.
I'm having bad times with creating typical card/deck class in java. I've read some similar questions & answers but either they're not relatable/helpful or I can't simply comprehend it yet.
Here's the code
public class Cards {
boolean isAvailable;
int card_id;
static final int AC = 32;
public Cards [] deck = new Cards[AC];
public void set () {
int a = 0;
for (int i = 0; i < AC; i++) {
if(a == 4) a = 0;
deck[i].isAvailable = true; // <---------
deck[i].card_id = i + (a * 101); // <---------
a++;
}
}
public void read () {
for (int i = 0; i < AC; i++)
System.out.println(deck[i].isAvailable + " " + deck[i].card_id);
}
public static void main (String[] args) {
Cards c = new Cards();
c.set();
c.read();
}
}
Exception in thread "main" java.lang.NullPointerException
at Cards.set(Cards.java:13)
at Cards.main(Cards.java:24)
1.
I've read about similar issues and found that problem can be in initialization of an array and I've tried to do the same with my prog but it went bad anyway.
I marked 13th and 14th lines because they are being pointed (when i comment 13th line just for check, pointer sets to the next line).
2.
Next part of help I would like to get from you is:
Even though there is main (for training purposes), I see other class using this class (which just creates deck) so I guess I won't be needing main... Is everything well set besides probs in first point?
Very simple:
public Cards [] deck = new Cards[AC];
creates an empty array with AC number of slots for Cards objects.
Now you have to put a non-null Cards object into each slot!
But thing is: actually your abstraction is broken.
You wrote code that seems to take one card to be the same as a card set - by adding that array of Cards into your Cards class! And that makes it actually hard to fix your current code. As the "normal" way to fix this would be to add a constructor like
public Cards() {
deck = new Cards[AC];
for (int i=0; i<deck.length;i++) {
deck[i] = new Cards();
}
If you try that ... you immediately run into an endless recursion (creating one new Cards would result in creating AC new Cards (to fill the array); causing a stackoverflow very soon.
Thus the real answer goes somewhere along these lines:
public class Card {
... a class that represents a SINGLE card in your game
and then
public card GameOfCards {
... a class that (for example!) uses an array to hold n objects of class Card!
Finally, as Peter is indicating in his comment: you should learn to use debugging means to work on such problems yourself. One good way: before using any data structure, iterate it and print out its content. Or even better, learn how to use a debugger, and walk through your code step by step! As you should please understand: this is very basic stuff; that you normally should not bring forward here.
Newbie completeing thinkJava book and trying to figure out one of the answers to the exercises. It calls for me to download the "GridWorld" files and complete the following steps:
Write a method named moveBug that takes a bug as a
parameter and invokes move. Test your method by calling it from main.
Modify moveBug so that it invokes canMove and moves the bug only if
it can.
Modify moveBug so that it takes an integer, n, as a parameter, and
moves the bug n times (if it can).
Modify moveBug so that if the bug can’t move, it invokes turn instead.
I am stuck on number 3, I can not figure out how to pass n into the "move() method"
-Please Help I am a newbie
My Code:
import info.gridworld.actor.ActorWorld;
import info.gridworld.actor.Bug;
import info.gridworld.actor.Rock;
public class BugRunner
{
public static void main(String[] args)
{
ActorWorld world = new ActorWorld();
Bug redBug = new Bug();
world.add(redBug);
world.add(new Rock());
world.show();
moveBug(redBug,5);
System.out.println(redBug.getLocation());
}
public static void moveBug(Bug aBug, int n){
if(aBug.canMove() == true){
aBug.move();
} else {
aBug.turn();
}
}
}
You mean you're stuck on number 3:
Modify moveBug so that it takes an integer, n, as a parameter, and moves the bug n times (if it can).
This means write a loop, looping n times, calling move() once per iteration, if canMove() returns true.
BTW: if (canMove() == true) {...} is the long way to say if (canMove()) {...}.
And fix the indentation of the if statement.
Thanks for pointing me #Andreas
My Solution that worked:
public static void moveBug(Bug aBug, int n){
for(int i = 0; i < n; i++){
if(aBug.canMove())
{
aBug.move();
} else {
aBug.turn();
}
}
}
I am attempting to access an ArrayList that was created in a different method within the same class. The scanner method pulls in data from a text file. The text file data appears this way: 123 12 1 43, with line breaks...
Currently, my method works to pull in the data, but does not compile after that method ends. I originally had the entire code within the same method and it worked fine. But I'd like to return the largest value by creating a new method within this class, and then create a tester class that will access this new method. Here is my existing code. Or if there is a better solution. I'm all ears.
public class DataAnalyzer {
public DataAnalyzer(File data) throws FileNotFoundException
{
List<Integer> rawFileData = new ArrayList<>();
FileReader file = new FileReader("info.txt");
try (Scanner in = new Scanner(file)) {
while(in.hasNext())
{
rawFileData.add(in.nextInt());
}
}
}
public int getLargest(rawFileData){
int largest = rawFileData.get(0);
for (int i = 1; i < rawFileData.size(); i++){
if (rawFileData.get(i) > largest)
{
largest = rawFileData.get(i);
}
}
for (Integer element : rawFileData){
if (element == largest)
{
System.out.print("This is the Largest Value: ");
System.out.print(element);
}
}
}
}
Your main issue is with your method declaration. It needs a type parameter:
public int getLargest(List<Integer> rawFileData)
Note the List<Integer>.
Now, there is already a method for this in the Collections utility class. You would do well to look over that link in detail - there are many useful methods there. To get the highest element from a Collection of Objects that have a natural order (such a Integer). For example
int largest = Collections.max(rawFileData)
So your method can be reduced to:
public int getLargest(List<Integer> rawFileData)
return Collections.max(rawFileData);
}
You need to think over your logic much more carefully before you begin to write code, for example, your first loop is good:
int largest = rawFileData.get(0);
for (int i = 1; i < rawFileData.size(); i++){
if (rawFileData.get(i) > largest)
{
largest = rawFileData.get(i);
}
}
You do exactly what any programmer would do. But then, instead of returning the largest when you find it, you for some reason loop again:
for (Integer element : rawFileData){
if (element == largest)
{
System.out.print("This is the Largest Value: ");
System.out.print(element);
}
}
Ask yourself what does this do? You have a List of, say, apples. You look at each one and compare them - finding the largest apple. You now have the largest apple in the List. You then loop over the List again looking for an apple that matches the apple you have already found. Why do this?
Further, you never return from the method. Your method is declared as returning an int; but you never do.
The missing type in your method definition is the problem here.
Change the method definition from
public int getLargest(rawFileData) {
....
}
to
public void getLargest(List<Integer> rawFileData) {
....
}
And the second for loop in the method is unnecessary. The largest integer is already stored in the variable "largest" and you can print it after the first for loop.
My professor gave me a code for the methods to be used in sorting an array of names lexicographically, but I have no idea how what to write inside the main class to show that the program works. I am very new to java, so please if you know how to do this could you write it as simple as possible for me to understand it. Thanks in advance.
This is are the classes
public class quicksort_class {
int[] array1 = new int[11];
public quicksort_class(int[] w)
{
array1 = w;
}
private static void sort(String[] string, int leftlimit, int rightlimit) {
if (rightlimit > leftlimit)
{
int midpoint = partitionstep(string, leftlimit, rightlimit);
sort(string, leftlimit, midpoint - 1);
sort(string, midpoint, rightlimit);
}
}
public static int partitionstep(String[] string, int leftlimit, int rightlimit)
{
String midpoint = string[rightlimit];
int lpointer = leftlimit;
int rpointer = rightlimit;
String temp = "";
while(string[lpointer].compareTo(midpoint) <= 0)
{
lpointer = lpointer ++;
}
while(string[rpointer].compareTo(midpoint) > 0)
{
rpointer = rpointer --;
}
if(lpointer > rpointer)
{
temp = string[lpointer];
string[lpointer] = string[rightlimit];
string[rpointer] = temp;
System.out.println(string);
}
while(lpointer < rpointer)
{
temp = string[lpointer];
string[lpointer] = string[rightlimit];
string[rightlimit] = temp;
}
return lpointer;
}
}
This is the main class (as you can see I have no idea what to write)
package quicksort;
public class Quicksort {
public static void main(String[] args) {
}
}
Write something that sets up an array of strings and calls sort against it, then prints out the results or checks them against a known good result.
Ideally, write something which does this repeatedly, with particular emphasis on checking unusual combinations (already sorted or sorted in reverse, null in the array, same value appearing several times or all values being identical...)
If you want to go beyond that, you need to dig into the code to understand its edge cases and specifically test those, and/or do a "code coverage" analysis (there are tools to help with that) to make sure all parts of the code have been exercised.
Assume the algorithm of sort method is correct:
1. If the main method is within the body of quicksort_class, you can directly call the sort method as sort(arrayToBeSorted, 0 , arrayToBeSorted.length-1). And the arrayToBeSorted should ordered lexicographically after your call. You can check that to confirm.
2. If the main method is in other class, as your main method currently, you need to at least change the private prefix of sort method to public, and call quicksort_class.sort(arrayToBeSorted, 0 , arrayToBeSorted.length-1).
Some tips:
1. Private prefix of method definition means this method can only be called inside current class body.
2. Static prefix of method definition means you should call this method via class name directly, instead of via a instance of class.
By the way, can you provide what the array1 attribute stands for? I don't get why it's there.