ArrayIndexOutOfBounds only at print - java

I dont understand why this is happening. without the print statement the code works fine but when i try to print the elements i get ArrayIndexoutOfBounds. For example if i try to feed 3 elements i get exception thrown. can anyone please explain
class MyClass
{
int search(OtherClass obs,target) {
double a[]=new double[obs.length];
for(int i=0;i<obs.length;i++)
{
a=obs[i].getTarget();
System.out.println(a[i]);//without this it does not throw
}
}
}
class OtherClass
{
String Target;
public String getTarget() {
return target;
}
public void setTarget(String target) {
this.target = target;
}
}

System.out.println(a)
but not
System.out.println(a[i])

In your code obs is an array: obs[i]; each position of that array is, itself, other array: obs[i].getTarget() #=> double[] I guess if, really obshas a method named getTarget() which returns an array.... probably this?
double a[] = new double[obs.length];
double obsArray[] = obs.getTarget();
for(int i=0; i<obs.length; i++){
a[i] = obs[i];
System.out.println(a[i]);
}

You should use this, this statement will set value from obs[i].getTarget() to a[i]
a[i]=obs[i].getTarget();
Edited:
If getTarget() method returns an array then you can this way,
for(int i=0;i<obs.length;i++)
{
double a[] =obs[i].getTarget(); // putting the array from getTarget() to a[]
for(int j=0;j<a.length;j++)
System.out.println(a[j]);//printing all the values of a[]
}

Related

Sorting String array gives NullPointerException

Hello I have implemented this basic program which should sort out the strings that are inserted however it somehow is failing to insert the strings .
For example if I implement :
TestSort t = new TestSort();
t.i("abc");
t.i("aab");
Can anybody see the error and help me fix this error please ?
Thank you
Here is the code :
public class TestSort {
private int length;
String[] data;
public TestSort() {
length = 0;
}
public void i(String value) {
data[length] = value;
setSorted(data);
length++;
}
public void setSorted(String data[]) {
for(int i = data.length-1; i >= 0; i--) {
for(int j = 0; j < i; j++) {
if(data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
for(int i = 0; i < data.length; i++) {
System.out.print(data[i] +" ");
}
}
}
You don't initialize the array data. So it is set null, and accesses with data[i] will get you an NullPointerException. Even if you initialize this field, it will not work, as Arrays in Java have a fixed size, you have to reallocate the Array, if you insert a new value. You should try a List-implementation instead.
So the code should initialize in the constructor:
data = new ArrayList<String>();
and insertion would change to
data.add(value);
you can change your constructor code as (String array max length can be taken as input parameter):
public testsort()
{
data = new String[10];
length = 0;
}
But if you are not sure with the size of array you can use ArrayList.
You are getting exception because you are comparing with data[j+1] that is still null.
first time when you call
t.i("abc");
there is only one reference in data array that is pointing to String literal "abc" and that is at index 0. index 1 is still referring to null.
first String is already sorted so no need to sort that. if you are having more than one string then you should call setSorted() method.
to solve this you can put your condition in loop as:
if((data[j] != null && data[j+1] != null) &&(data[j].compareTo(data[j + 1]) > -1))
A working example but still: use a List and life is much easier :-)
public class Test {
private int length;
private String[] data;
public Test(int arrayLength) {
// INITIALIZE YOU ARRAY --> No NULLPOINTEREXCEPTION!
data = new String[arrayLength];
length = 0;
}
public void i(String value) {
data[length] = value;
length++;
}
public void setSorted() {
for (int j = 0; j < data.length - 1; j++) {
if (data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
for (String s : data) {
System.out.println(s);
}
}
public static void main(String[] args) {
Test t = new Test(5);
t.i("bbb");
t.i("aaa");
t.i("ccc");
t.i("zzz");
t.i("ddd");
// USE SETSORTED HERE --> else you fill your array with the same elements
t.setSorted();
}
}
The variable 'data' is null since it is nowhere initialized hence giving null pointer exception. Since 'data' is an array and as per the rule whenever an array is defined, it has to be of defined length. for e.g if we consider your case. 'data' can be initialized as :-
String[] data = new String[any numerical value]
the numerical value will be its length i.e. the maximum number of elements it can hold.
Secondly, as per your program statement :-
data[length] = value;
is trying to assign value at data's [length] index which is completely wrong since you haven't defined the length therefore how could you guess the index's value. Therefore your this approaoch is logically wrong.
For such situation i.e. whenever we're unaware about the length of the array, use of ArrayList is suggested. Therefore your program can be re-written by two ways:-
1) Either define the length of the array
String[] data = new String[n];
where n ranges from at least 1 to any positive integer.
2) By using ArrayList
public class Main {
List<String> data;
public Main(){
data = new ArrayList<String>();
}
public static void main(String... q){
Main m = new Main();
m.insertData("abc");
m.insertData("zxy");
m.insertData("aab");
m.insertData("aaa");
m.showData();
}
public void insertData(String str){
data.add(str);
Collections.sort(data);
}
public void showData(){
if(data!=null && !data.isEmpty()){
for(String s : data){
System.out.println(s);
}
}
}
}
output:-
aaa
aab
abc
zxy
Hope this helps.
as Mnementh suggested, the reason for NPE is that you have created the field data of type String[] but you never initialized it.
Other answers have provided every reason on why your code throwing ugly errors; I have just improved your code by replacing your String[] with List<String> so you don't have to worry about the size of your array anymore.
Sorting is also simplified now using Collections.sort().
have a look,
class test1 {
public static void main(String[] args) {
Test sorting = new Test();
sorting.input("abc");
sorting.input("cba");
sorting.input("aab");
sorting.setSorted();
}
}
class Test {
private List<String> data = new ArrayList<String>();
public void input(String value) {data.add(value);}
public void setSorted() {
Collections.sort(data);
for (String current : data) {
System.out.println(current);
}
}
}
if you are using Java 8, then you can use Arrays.parallerSort(), it performs sorting the same way as Collection.sort but with a parallel implementation.
Current sorting implementations provided by the Java Collections Framework > (Collections.sort and Arrays.sort) all perform the
sorting operation sequentially in the calling thread. This enhancement
will offer the same set of sorting operations currently provided by
the Arrays class, but with a parallel implementation that utilizes the
Fork/Join framework. These new API's are still synchronous with regard
to the calling thread as it will not proceed past the sorting
operation until the parallel sort is complete.
to implement it, replace Collections.sort with Arrays.parallelSort in the above code,
Replace,
Collections.sort(data);
with,
Arrays.parallelSort(data.toArray(new String[data.size()]));

My test method is returning null when I run it

Apologies if the answer to this question is obvious! I've tried to initialize my field numbers with an array of numbers in a constructor in one class and then call it in my test class and display it as a string but it keeps returning null....any help would be appreciated!
This is my class that has the constructor:
public class NumerbList implements Number {
ArrayList<Number> numbers = new ArrayList<Number>();
//constructor taking array of type double as parameter
public NumberList(Double[] numberlist){
for(int i=0; i<numbers.size(); i++){
NumberDouble numberd = new NumberDouble(numberlist[i]);
numbers.add(numberd);
}
}
and the test class that creates an object of the NumberList class
public class Test {
public static void main(String[]args){
Double[] d = {2.4, 3.6, 4.3, 5.1};
NumberList numbers = new NumberList(d);
numbers.neg();
System.out.print(numbers.asString());
}
}
sorry neg is as follows :
public void neg(){
for(int i=0; i < numbers.size(); i++){
numbers.get(i).neg();
}
}
and asString is :
#Override
public String asString(){
return numbers.toString();
}
Should I put
for(int i=0; i < numberlist.length(); i++;)
in neg?
Thanks in advance!
The problem is that your for loop is using your initialize empty ArrayList as the size.
Change your loop to this:
for (int i = 0; i < numberlist.length; i++) {
// your loop logic here
}
Hope that helps!
for(int i=0; i<numbers.size(); i++){ should be for(int i=0; i<numberList.length; i++){
Also note that there is an easier (and generally preferred) way to iterate over your array:
for (Double number : numberlist) {
// your loop logic here
}
(I'd post that as a comment but it would lose the code formatting).

'.class' expected. array method error

public class warm4{
public static void main(String[] args){
double scale = 3;
double[] array = {1,2,3};
}
public static double[] scalarMultiply(double[] array, double scale){
for( int i=0; i>array.length; i++){
array[i] = (array[i])*scale;
}
return array[]; **//error here!**
}
}
I dont know how to correct that error!
thank you in advance!
return array; **// Now no error here!**
No need for that extra [].
[] is a syntax part of array declaration time to specify length of array.
So need to add that while returning that array. Just use variable name.
array[] doesn't make sense.
If you want to return the value of a variable, just return that variable.

Java, Return true if array contains duplicate values

I am trying to have a method (duplicates) return true if a given array called x (entered by user in another method), contains duplicate values. Otherwise it would return false. Rather then checking the entire array, which is initialized to 100, it will check only the amount of values entered, which is kept track of with a global counter: numElementsInX.
What is the best way to accomplish this?
public static boolean duplicates (int [] x)
I am prompting for user data like so:
public static void readData (int [] x, int i){
Scanner input = new Scanner(System.in);
System.out.println("Please enter integers, enter -999 to stop");
while (i <= 99) {
int temp = input.nextInt();
if(temp == -999){
break;
}
else {
x[i++]=temp;
}
// else
}//end while
printArray(x,i);
}//end readData
public static void printArray(int [] x, int numElementsInX){
int n = numElementsInX;
for (int i = 0; i < n; i++){
System.out.print(x[i] + " ");
}//end for
System.out.println();
}//end printArray
I am sure there is a better way to do this, but this is how I have been taught so far.
Here is a solution that:
Compiles and executes without throwing.
Uses numElementsInX as you requested.
Returns as soon as it finds a duplicate.
This approach tests whether each member of the array has been seen before. If it has, the method can return immediately. If it hasn't, then the member is added to the set seen before.
public static boolean duplicates (int [] x, int numElementsInX ) {
Set<Integer> set = new HashSet<Integer>();
for ( int i = 0; i < numElementsInX; ++i ) {
if ( set.contains( x[i])) {
return true;
}
else {
set.add(x[i]);
}
}
return false;
}
Here's a sample program containing the above code.
this should do it.
public boolean containsDuplicates(Integer[] x) {
return new HashSet<Integer>(Arrays.asList(x)).size() != x.length
}
You dont need numElementsInX as this is the same as x.length
edit after comment from Louis. Arrays.asList does not work with int arrays.
To convert int[] to Integer try this question How to convert int[] to Integer[] in Java?
or do soemthing like this (not tested but from memory)
Integer[] newArray = new Integer[a.length];
System.arraycopy(a, 0, newArray, 0, a.length);
This certainly isn't the most efficient way, but since you don't know about Sets yet, you can use two loops:
public static boolean duplicates (int [] x){
for (int i=0; i<numElementsInX; i++){
for (int j=i+1; j<numElementsInX; j++){
if (x[j]==x[i]) return true;
}
}
return false;
}
"set.add()" returns true if the element is not already present in the set and false otherwise. We could make use of that and get rid of "set.contains()" as in the above solution.
public static boolean duplicates (int[] x, int numElementsInX) {
Set<Integer> myset = new HashSet<>();
for (int i = 0; i < numElementsInX; i++) {
if (!myset.add(x[i])) {
return true;
}
}
return false;
}
For java, return true if the array contains a duplicate value,
boolean containsDuplicates(int[] a) {
HashSet<Integer> hs = new HashSet<>();
for(int i = 0; i<a.length; i++) {
if(!hs.add(a[i])){
return true;
}
}
return false;
}

Java - Returning from a recursive function

I'm trying to return all possible permutations of values in a String array. I've come up with the following code making all possible permutations; it works fine.
private void combineArray(String sPrefix, String[] sInput, int iLength) {
if (iLength == sPrefix.length()) {
//This value should be returned and concatenated:
System.out.println(sPrefix);
} else {
for (int i=0; i<sInput.length; i++) {
combineArray(sPrefix.concat(sInput[i]), ArrayUtils.removeElement(sInput, sInput[i]), iLength);
}
}
}
If I put in {x, y ,z} it prints to the console:
xyz
xzy
yxz
yzx
zxy
zyx
My problem is that I can't find a way to return these values to the original calling function. So I'd like this function not to return 'void' but a 'String' containing the concatened values of sPrefix.
I've been struggling with this for a while now and I can't seem to see clearly anymore. :) Any help would be appreciated.
Rather than returning a list, I think it might work better to pass in a list as an argument, and populate it inside the method:
private void combineArray(List<String> lOut, String sPrefix, String[] sInput, int iLength) {
if (iLength == sPrefix.length()) {
//This value should be returned and concatenated:
System.out.println(sPrefix);
lOut.add(sPrefix);
} else {
for (int i=0; i<sInput.length; i++) {
combineArray(lOut, sPrefix.concat(sInput[i]), ArrayUtils.removeElement(sInput, sInput[i]), iLength);
}
}
}
You can then have a wrapper method that creates the new ArrayList<String>, passes it into the above method, and returns it.
You can have an ArrayList<String> and add all the strings to it.. And then you can return this ArrayList..
List<String> listString = new ArrayList<>();
private void combineArray(String sPrefix, String[] sInput, int iLength) {
if (iLength == sPrefix.length()) {
listString.add(sPrefix);
//This value should be returned and concatenated:
System.out.println(sPrefix);
} else {
for (int i=0; i<sInput.length; i++) {
combineArray(sPrefix.concat(sInput[i]), ArrayUtils.removeElement(sInput, sInput[i]), iLength);
}
}
return listString;
}
Keep appending to the same output.. Like this:
private String combineArray(String sPrefix, String[] sInput, int iLength, String output) {
if (iLength == sPrefix.length()) {
//This value should be returned and concatenated:
System.out.println(sPrefix);
output = output+"|+sPrefix;
return output;
} else {
for (int i=0; i<sInput.length; i++) {
output = combineArray(sPrefix.concat(sInput[i]), ArrayUtils.removeElement(sInput, sInput[i]), iLength, output);
}
}
}
You can also use a ListArray instead of a String, once the basic concept works..

Categories

Resources