Simple ArrayIndexOutOfBoundsException 1 in loop - loops

I have a .data file containing lines of values. I partition them into separate values using the split method, then I initialize an ArrayList where I add the model items to the list. I had a while loop for this specific code here which looked like this:
while (inFile.hasNextLine() {
// Do something
}
That didn't seem to work so I switched it to a for loop.
public MachineLearningInstance(File f) {
try {
int noOfRowsInData = 0;
LineNumberReader lnr = new LineNumberReader(new FileReader(f));
try {
lnr.skip(Long.MAX_VALUE);
noOfRowsInData = lnr.getLineNumber();
//System.out.println(noOfRowsInData);
lnr.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
irisData = new ArrayList<Iris>();
// While there is another line in inFile.
Scanner inFile = new Scanner(f);
for (int i = 0; i < noOfRowsInData; i++) {
if (inFile.hasNextLine()) {
// Store line into String
String line = inFile.nextLine();
// Partition values into separate elements in array
String[] numbers = line.split(comma);
// Grab values from that line and store it into a Iris ArrayList Item
irisData.add(i, new Iris(i, numbers[0], numbers[1], numbers[2], numbers[3], numbers[4]));
}
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
For some weird reason (and I bet it is a really simply reason I just can't see it) I keep getting the ArrayListIndexOutOfBoundsException 1 when I run this piece of code. I'm guessing that my while loop keeps looping? I don't understand what the problem seems to be.
Is it possible that my LineNumberReader is not reading the number of lines properly? I don't think that is the case though. Most likely I am not declaring something correctly.

So this happened to solve my problem, I'm really tired and have no interest right now in finding out why but it fixed the issue lol:
for (int i = 0; i < noOfRowsInData - 1; i++) {
if (inFile.hasNextLine()) {
// Store line into String
String line = inFile.nextLine();
// Partition values into separate elements in array
String[] numbers = line.split(comma);
// Grab values from that line and store it into a Iris ArrayList Item
irisData.add(i, new Iris(i, numbers[0], numbers[1], numbers[2], numbers[3], numbers[4]));
}
}
Supposedly noOfRowsInData - 1 fixes it.

Related

NullPointerException on an array of strings

My purpose is to get what a user types in and to store them in the array "info", then convert the info[0] into upper case. However, when I compile my code, I always got the message Exception in thread "main" java.lang.NullPointerException at the line "info[0]=info[0].toUpperCase();". But I totally have not idea what causes this exception. If anyone can tell me the cause, it would be great. Thank you!
public static void main(String[] args)
{
Scanner userScan = new Scanner(System.in);
String keyboard = userScan.nextLine();
StringTokenizer tokens = new StringTokenizer(keyboard, " ");
String[] info= new String[4];
for(int i=0; tokens.hasMoreTokens(); i++)
{
info[i] = tokens.nextToken();
}
info[0]=info[0].toUpperCase();
//other codes...
}
When you try to execute the code without any tokens, It would skip past the for loop, and try to perform
info[0].toUpperCase();
But since the for loop has been skipped info object is initialized to null.
Thus trying to access it would give you an Null Pointer Exception.
Just move the conversion inside the for loop to avoid this.
for(int i=0; tokens.hasMoreTokens(); i++){
info[i] = tokens.nextToken();
//converts only when value exists
info[i]=info[i].toUpperCase();
}

Processing - How to log Strings in txt file?

Im getting more and more frustrated on why this is not doing what i want to. I need to have a text file that logs the last 10 buttons the user pressed, i tried in two ways but…
…this code only saves the last button pressed:
String [][] buttonsPressed = { {"Pressed one"}, {"Pressed two"} };
String[] sum;
void setup() {
size(700, 350);
sum = loadStrings("scores.txt");
}
void draw() {
}
void keyPressed() {
if ((key=='1')) {
saveStrings("scores.txt", buttonsPressed[0]);
}
if ((key=='2')) {
saveStrings("scores.txt", buttonsPressed[1]);
}
if ((key == ENTER)) {
printArray(sum);
}
}
…this code saves the buttons pressed but overwrites itself when i run the sketch again (probably has something to do with createWriter):
PrintWriter sum;
void setup() {
size(700, 350);
sum = createWriter("scores.txt");
}
void draw() {
}
void keyPressed() {
if ((key=='1')) {
sum.println("pressed one");
}
if ((key=='2')) {
sum.println("pressed two");
}
if ((key == ENTER)) {
sum.flush();
sum.close();
String[] lines = loadStrings("scores.txt");
for (int i = 0; i <= 9; i++) {
printArray("[" + i + "] " + lines[i]);
}
}
}
Is there a simple way to do this without using libraries ? Please get me in the right direction :)
Break your problem down into smaller steps.
Step 1: At the beginning of your program, read in the existing history file. Store them in some kind of data structure, like an array or an ArrayList.
Step 2: Make the data structure keep track of the last 10 buttons pressed. You'll need to write code that adds the newest button pressed to the end of the data structure, and if the data structure contains more than 10 items, you have to remove the oldest item. Maybe do this in a separate example sketch where you just print the data structure to the console and don't worry about outputting it to a file just yet.
Step 3: Output the data structure to a file. You don't have to worry about appending to the file because your data structure contains the entire history, so you can just overwrite the file with the entire data structure. You'll probably want to do this every time the data structure changes. Again, maybe do this in a separate example program before worrying about where the data is coming from: maybe make a program that outputs an array of random numbers every time the user clicks?
Focus on one small step at a time, and try creating small example programs for each step. Then when you get stuck, you can ask a specific question and provide an MCVE, and we'll go from there. Good luck.

Array throwing exception

I can't seem to put my finger on this and why the array is not being initialized.
Basically I am coding a 2d top down spaceship game and the ship is going to be fully customizable. The ship has several allocated slots for certain "Modules" (ie weapons, electronic systems) and these are stored in an array as follows:
protected Array<Weapon> weaponMount;
Upon creating the ship none of the module arrays are initialized, since some ships might have 1 weapon slot, while others have 4.
So when I code new ships, like this example:
public RookieShip(World world, Vector2 position) {
this.width = 35;
this.height = 15;
// Setup ships model
bodyDef.type = BodyType.DynamicBody;
bodyDef.position.set(position);
body = world.createBody(bodyDef);
chassis.setAsBox(width / GameScreen.WORLD_TO_BOX_WIDTH, height / GameScreen.WORLD_TO_BOX_HEIGHT);
fixtureDef.shape = chassis;
fixtureDef.friction = 0.225f;
fixtureDef.density = 0.85f;
fixture = body.createFixture(fixtureDef);
sprite = new Sprite(new Texture(Gdx.files.internal("img/TestShip.png")));
body.setUserData(sprite);
chassis.dispose();
// Ship module properties
setShipName("Rookie Ship");
setCpu(50);
setPower(25);
setFuel(500);
setWeaponMounts(2, world);
setDefenseSlots(1);
addModule(new BasicEngine(), this);
addModule(new BasicBlaster(), this);
// Add hp
setHullHP(50);
setArmorHP(125);
setShieldHP(125);
}
#Override
public void addModule(Module module, Ship currentShip) {
// TODO Auto-generated method stub
super.addModule(module, currentShip);
}
#Override
public void setWeaponMounts(int weaponMounts, World world) {
weaponMount = new Array<Weapon>(weaponMounts);
// super.setWeaponMounts(weaponMounts, world);
}
#Override
public String displayInfo() {
String info = "Everyones first ship, sturdy, reliable and only a little bit shit";
return info;
}
When I set the number of weapon mounts the following method is called:
public void setWeaponMounts(int weaponMounts, World world) {
weaponMount = new Array<Weapon>(weaponMounts);
}
This basically initializes the array with a size (weapon mounts available) to whatever the argument is. Now to me this seems fine but I have setup a hotkey to output the size of the Array, which reports zero. If I try to reference any objects in the array, it throws an outofbounds exception.
The addModule method adds to the array as follows:
public void addModule(Module module, Ship currentShip) {
currentShip.cpu -= module.getCpuUsage();
currentShip.power -= module.getPowerUsage();
if(module instanceof Engine){
engine = (Engine) module;
}else if(module instanceof Weapon){
if(maxWeaponMounts == weaponMount.size){
System.out.println("No more room for weapons!");
}else{
maxWeaponMounts += 1;
weaponMount.add((Weapon)module);
}
}
}
My coding ain't great but heh, better than what I was 2 month ago....
Any ideas?
First of all, You should avoid instanceof. It's not a really big deal performance-wise, but it always points to problems with your general architecture. Implement two different addModule methods. One that takes a Weapon, and one that takes an Engine.
Now back to topic:
else if(module instanceof Weapon){
if (maxWeaponMounts == weaponMount.size) {
System.out.println("No more room for weapons!");
} else{
maxWeaponMounts += 1;
weaponMount.add((Weapon)module);
}
}
It looks like you use maxWeaponMounts as a counter instead of a limit. That's why I assume that it will initially be 0. The same holds for Array.size. It is not the limit, but size also counts how many elements the Array currently holds. Thus you will always have (maxWeaponMounts == weaponMount.size) as 0 == 0 and you will not add the weapon to the array. It will always stay empty and trying to reference any index will end in an OutOfBoundsException.
What you should actually do is using maxWeaponMounts as a fixed limit and not the counter.
public void setWeaponMounts(int weaponMounts, World world) {
weaponMount = new Array<Weapon>(weaponMounts);
maxWeaponMounts = weaponMounts;
}
else if(module instanceof Weapon){
if (weaponMount.size >= maxWeaponMounts) {
System.out.println("No more room for weapons!");
} else{
weaponMount.add((Weapon)module);
}
}

How to read and add only numbers to array from a text file

I'm learning java and I have a question regarding reading from file
i want to read only numbers from file that contains strings as well.
here is an example of my file:
66.56
"3
JAVA
3-43
5-42
2.1
1
and here is my coding:
public class test {
public static void main (String [] args){
if (0 < args.length) {
File x = new File(args[0]);
try{
Scanner in = new Scanner( new FileInputStream(x));
ArrayList<Double> test = new ArrayList<>();
while(in.hasNext()){
if(in.hasNextDouble()){
Double f=in.nextDouble();
test.add(f);}
else
{in.next();}
}
catch(IOException e) { System.err.println("Exception during reading: " + e); }
}
my problem is it only add 66.56,2.1 and 1
it doesn't add 3 after "3 or it ignores 3-43 and 5-42
can you tell me how to skip Strings and only add doubles here?
thanks
All the said three ie; "3, 3-43 and 4-42 are strings
Either u read a string and split it and check for number at " and - or you put in a space between characters and integers.
The JVM after compilation would treat it all as string if it cannot be converted to a double.
And the File reader wont stop reading till at least a space or a newline.
Hence your code would never work the way you intend it to unless you do as I said above.
Solution 1:
Change your input file to something like this:
66.56
" 3
JAVA
3 - 43
5 - 42
2.1
1
Solution 2:
Considering the highly variable nature of your input file I am posting a solution only made for your current input. If the input changes a more versatile algorithm would need to be implemented.
public static void main(String[] args) {
File x = new File(args[0]);
try {
Scanner in = new Scanner(new FileInputStream(x));
ArrayList<Double> test = new ArrayList<>();
while (in.hasNext()) {
if (in.hasNextDouble()) {
Double f = in.nextDouble();
test.add(f);
} else {
String s=in.next();
if(s.contains("\"")){
String splits[]=s.split("\"");
test.add(Double.parseDouble(splits[1]));
}
else if (s.contains("-")){
String splits[]=s.split("-");
test.add(Double.parseDouble(splits[0]));
test.add(Double.parseDouble(splits[1]));
}
}
}
System.out.println(test);
} catch (IOException e) {
System.err.println("Exception during reading: " + e);
}
}
You can write custom Type Sensor Utility class to check whether the object can be converted to Integer or not. I would approach to this problem like this.
Moreover I can see that you have values like 2.1 and " 3 to handle these scenarios write additional methods like isDoubleType() or isLongType() etc.
Also you need to write some custom logic to solve this problem.
public class TypeSensor {
public String inferType(String value) throws NullValueException {
int formatIndex = -1;
if (null == value) {
throw new NullValueException("Value provided for type inference was null");
}else if (this.isIntegerType(value)) {
return "Integer";
}else{
LOGGER.info("Value " + value + " doesnt fit to any predefined types. Defaulting to String.");
return "String";
}
}
}
private boolean isIntegerType(String value) {
boolean isParseable = false;
try {
Integer.parseInt(value);
LOGGER.info("Parsing successful for " + value + " to Integer.");
isParseable = true;
} catch (NumberFormatException e) {
LOGGER.error("Value " + value + " doesn't seem to be of type Integer. This is not fatal. Exception message is->"
+ e.getMessage());
}
return isParseable;
}
}

Delete records using integer list

I want to Loop through the array of integers and want to remove the items in the TLToProcess list which i have stored in the array of integers
here is the code
I want to remove only the selected in the list integer
iSize.add(TLToProcess.size());
if(TLToProcess[i].Scan_In1__c==null)
{
if(TLToProcess[i].typew__c=='Pending')
{
TLForMissingHHhh.add(TLToProcess[i]);
}
}
else if ( c[i].Scan_In1__c!=null)
{
if (TLToProcess[i].typew__c=='Pending' )
{
TLToProcess[i].typew__c='Processed';
}
}
}
Now i want to remove record 1 by 1 from TLToProcess using
remove() can any body tell me how to do it.
Thanks
Anu
Not sure I understand your problem, but if what you're trying to avoid is modifying your List of integers inside a loop and getting this error: {"Collection was modified; enumeration operation may not execute."} you can create a copy of your List(.ToList()) and use it to iterate, and this way you can call Remove() safely.
List<Int32> arr = new List<Int32>();
for (int i = 0; i < 10; i++)
{
arr.Add(i);
}
foreach(var o in arr.ToList())
{
arr.Remove(o);
}
Is that the intent?

Resources