While iterating the two lists and displaying the items in the layouts i m getting the Array Index out of bounds exception at the line below.How can we have a null check or a condition with which i wont get the error
ParallelList<BaseItem> list = new ParallelList<BaseItem>(highlighted, normal);
for (List<BaseItem> ints : list) {
final BaseItem itemH = ints.get(0);
if(!ints.get(1).equals(null) && ints.size()!=0){ // error here at this line
final BaseItem itemn = ints.get(1);
}
using the below parallellist for this
public class ParallelList<T> implements Iterable<List<T>> {
private final List<List<T>> lists;
public ParallelList(List<T>... lists) {
this.lists = new ArrayList<List<T>>(lists.length);
this.lists.addAll(Arrays.asList(lists));
}
public Iterator<List<T>> iterator() {
return new Iterator<List<T>>() {
private int loc = 0;
public boolean hasNext() {
boolean hasNext = false;
for (List<T> list : lists) {
hasNext |= (loc < list.size());
}
return hasNext;
}
public List<T> next() {
List<T> vals = new ArrayList<T>(lists.size());
for (int i=0; i<lists.size(); i++) {
if(loc < lists.get(i).size()){
vals.add(lists.get(i).get(loc));
}
// vals.add(loc < lists.get(i).size() ? lists.get(i).get(loc): null);
}
loc++;
return vals;
}
public void remove() {
for (List<T> list : lists) {
if (loc < list.size()) {
list.remove(loc);
}
}
}
};
}
}
Error is here
java.lang.IndexOutOfBoundsException: Invalid index 1, size is 1
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
You should reverse the conditions. First make sure the size of the list is large enough (i.e. it has more than one element), and only then attempt to access the second element of the list :
if(ints.size() > 1 && ints.get(1) != null)
Turn it around:
if(ints.size()!=0 && !ints.get(1).equals(null))
The && connection is evaluatef from left to right. So when the size is 0 then the left part is false already. The full && expression cannot be true regarless what !ints.get(1).equals(null) gets evaluated to. Therefore it will not be executed at all.
BTW, the first element has the index 0. You really want to use:
if(ints.size()!=0 && !ints.get(0).equals(null))
or
if(ints.size()<=2 && !ints.get(1).equals(null))
PS: Having a closer look at the error message, it turns out that the latter really fixes your problem. Size is actually 1 but you are accessing the second item with the index 1. (Again, first index is 0)
You should try these conditions
if(!ints.isEmpty()){
final BaseItem itemH = ints.get(0);
if( ints.size()>=1 && !ints.get(1).equals(null) ){
final BaseItem itemn = ints.get(1);
}
}
}
Related
I need to maintain a sorted data structure from which items can be deleted and added. For that I decided to choose a linked list. Each data item contains a letter and some numbers such as these:
A1480, A1488, B1297, C3119
These need to be maintained in order. I have written code for it which first finds the position into the already sorted linked list where the new item needs to be added and then adds the item to its correct position, therefore maintaining the sorted linked list. It works but some items are misplaced and I am not sure how to fix my code. I do know that there is something wrong with the last loop but i am not sure what it is.
public static void main(String[] args) {
list = new LinkedList<String>();
add("C3138");
add("C3119");
add("A1488");
add("A1480");
add("A1517");
add("B1297");
add("C2597");
add("B1356");
add("C9000");
add("C3517");
add("C3729");
add("C1729");
add("B1729");
}
public static void add(String value) {
// Integer value form the string passed into the method
int valueInt = getInt(value);
// If linked list is empty, add value and return from method
if (list.size() == 0) {
list.add(value);
return;
}
// Compare this item to be added to the first item
int firstNode = getInt(list.get(0));
if (list.get(0).charAt(0) > value.charAt(0)
|| (list.get(0).charAt(0) == value.charAt(0) && firstNode > valueInt)){
list.add(0, value);
return;
}
// Compare this item to the last item
int lastNode = getInt(list.get(list.size() - 1));
if (list.get(list.size() - 1).charAt(0) < value.charAt(0) ||
(list.get(list.size() - 1).charAt(0) == value.charAt(0) && lastNode < valueInt)) {
list.add(list.size(), value);
return;
}
// add the inbetween items
int i = 1;
int tempInt = getInt(list.get(i));
while ((list.get(i).charAt(0) < value.charAt(0)
|| ((list.get(i).charAt(0) == value.charAt(0)) && (valueInt < tempInt)) && i < list.size())) {
tempInt = getInt(list.get(i));
i++;
}
list.add(i, value);
}
public static int getInt(String item) {
return Integer.parseInt(item.replaceAll("\\D", ""));
}
This code below gives me output of:
[A1480, A1517, A1488, B1729, B1297, B1356, C1729, C3729, C3517, C2597,
C3119, C3138, C9000]
and as you can see that some values in between start and finish are misplaced but start and end values are correct. Please help
Try doing this :: Change your last while condition to this::
(list.get(i).charAt(0) < value.charAt(0) || ((list.get(i).charAt(0) == value.charAt(0)) && (valueInt > tempInt)) && i < list.size())
What you are currently doing is that you are incrementing your i unless you hit a value of tempInt which is smaller than varInt, which is why A1517 gets inserted before A1488.
You shall increment your i until the value of tempInt is smaller than `varInt so that you reach the largest position the current element could achieve. I hope I could make it clear.
The working code Ideone link :: http://ideone.com/ZafWEO
Further, it would be better to check the value to i before accessing the linkedlist items. So, the condition shall look like this ::
(i < list.size() && (list.get(i).charAt(0) < value.charAt(0) || ((list.get(i).charAt(0) == value.charAt(0)) && (valueInt > tempInt)))
Take a look at Why is there no SortedList in Java?
If your values are unique, you can just use TreeSet. Generally, if you want a sorted collection, you probably don't want to start with LinkedList.
Why don't you use Comparable?
Scroll to bottom to see the class implemented Comparable
This is answer to your question:
private static LinkedList<SuperRosie> list;
public static void main(String[] args) {
// TODO Auto-generated method stub
list = new LinkedList<SuperRosie>();
add("C3138");
add("C3119");
add("A1488");
add("A1480");
add("A1517");
add("B1297");
add("C2597");
add("B1356");
add("C9000");
add("C3517");
add("C3729");
add("C1729");
add("B1729");
for (int i = 0; i < list.size(); i++)
System.out.println(list.get(i).getValue());
}
private static void add(String value) {
SuperRosie myNewRs = new SuperRosie(value);
int listSize = list.size();
// If linked list is empty, add value and return from method
if (listSize == 0) {
list.add(myNewRs);
return;
}
// Compare this item to be added to the first item
SuperRosie element = list.getFirst();
if (myNewRs.compareTo(element) <= 0) {
list.addFirst(myNewRs);
return;
}else{
if(listSize == 1){
list.addLast(myNewRs);
return;
}
}
// Compare this item to the last item
element = list.getLast();
if (myNewRs.compareTo(element) >= 0) {
list.addLast(myNewRs);
return;
}else{
if(listSize == 1){
list.addFirst(myNewRs);
return;
}
}
// add the inbetween items
int compare = 0;
for (int i = 1; i < listSize; i++) {
element = list.get(i);
compare = myNewRs.compareTo(element);
if (compare <= 0) {
list.add(i, myNewRs);
break;
}
}
}
Example to Sort comparable Linked List:
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
LinkedList<SuperRosie> list = new LinkedList<SuperRosie>();
list.add(new SuperRosie("C3138"));
list.add(new SuperRosie("C3119"));
list.add(new SuperRosie("A1488"));
list.add(new SuperRosie("A1480"));
list.add(new SuperRosie("A1517"));
list.add(new SuperRosie("B1297"));
list.add(new SuperRosie("C2597"));
list.add(new SuperRosie("B1356"));
list.add(new SuperRosie("C9000"));
list.add(new SuperRosie("C3517"));
list.add(new SuperRosie("C3729"));
list.add(new SuperRosie("C1729"));
list.add(new SuperRosie("B1729"));
Collections.sort(list);
for(SuperRosie rs : list)
System.out.println(rs.getValue());
}
}
And SuperRosie.java class implements from Comparable
public class SuperRosie implements Comparable<SuperRosie> {
private String value;
public SuperRosie(String value) {
this.value = value;
}
public String getValue() {
return value;
}
#Override
public int compareTo(SuperRosie arg0) {
int compareFirst = this.value.charAt(0) - arg0.value.charAt(0);
return compareFirst == 0 ? (Integer.parseInt(this.value.replaceAll(
"\\D", "")) - Integer
.parseInt(arg0.value.replaceAll("\\D", ""))) : compareFirst;
}
public static Comparator<SuperRosie> FruitNameComparator = new Comparator<SuperRosie>() {
public int compare(SuperRosie rosie1, SuperRosie rosie2) {
String rosieValue1 = rosie1.value.toUpperCase();
String rosieValue2 = rosie2.value.toUpperCase();
// ascending order
return rosieValue1.compareTo(rosieValue2);
// descending order
//return rosieValue2.compareTo(rosieValue1);
}
};
}
According to the performance problems, I suggest another performance solution.
private static LinkedList<String> list;
public static void main(String[] args) {
list = new LinkedList<>();
add("C3138");
add("C3119");
add("A1488");
add("A1480");
add("A1517");
add("B1297");
add("C2597");
add("B1356");
add("C9000");
add("C3517");
add("C3729");
add("C1729");
add("B1729");
for (int i = 0; i < list.size(); i++)
System.out.println(list.get(i));
}
private static void add(String value){
// don't check empty array, check to add in the first, last element.
// Each case, it works but when array has more than 1 element,
// so the above check are useless, run will cost memory, steps,....
// So don't, please do just the following
int insertIndex = 0;
for(String element : list){
if(compare(value, element) <= 0){ // or whatever compare way you want
break;
}else{
insertIndex+=1;
}
}
list.add(insertIndex, value);
}
private static int compare(String value1, String value2){
int compareFirst = value1.charAt(0) - value2.charAt(0);
return compareFirst == 0 ? (Integer.parseInt(value1.replaceAll(
"\\D", "")) - Integer
.parseInt(value2.replaceAll("\\D", ""))) : compareFirst;
}
I have an array and I am implementing a priority queue with it. Now, I cam not shift the elements(since only the front pointer has to move).
I tried that by adding null to that array position but it just does not work since I have used Arrays.sort(arr) methods and if I do make the position null, it gives NullPointerException.
Here is how my code looks:
public static void remove() {
//Priorityy x = arr[front];
arr[front] = null;
front--;
//return x;
}
public int compareTo(Priorityy pe) {
if (this == null || pe == null)
return 0;
else {
if (this.key < pe.key) {
return 1;
} else if (this.key > pe.key) {
return -1;
} else {
return 0;
}
}
}
Where did I go wrong?
Use Arrays.copyOfRange to get an array without the first element (front) as follows:
arr = Arrays.copyOfRange(1, arr.length);
Where is the possible memory leak in my code? There is also supposed to be a programming error too in one the methods as well, that might cause problems if I create a subclass of this class.
The add method basically just takes an index of where to add the item. For every item that occupies anything after the index in the current array, it just copies it over a spot over, and then places the item into index. I don't see what's wrong with it.
For the remove method, it does the same thing basically, except in reverse.
private static final int MAX_LIST = 3;
protected Object []items;
protected int numItems;
public MyArray()
{
items = new Object[MAX_LIST];
numItems = 0;
}
/*the programming error should be in this method*/
public void add(int index, Object item)
throws ListIndexOutOfBoundsException
{
if (numItems > items.length)
{
throw new ListException("ListException on add");
}
if (index >= 0 && index <= numItems)
{
for (int pos = numItems-1; pos >= index; pos--)
{
items[pos+1] = items[pos];
}
items[index] = item;
numItems++;
}
else
{
throw new ListIndexOutOfBoundsException(
"ListIndexOutOfBoundsException on add");
}
}
/*The memory leak should be in this method*/
public void remove(int index)
throws ListIndexOutOfBoundsException
{
if (index >= 0 && index < numItems)
{
for (int pos = index+1; pos < numItems; pos++)
{
items[pos-1] = items[pos];
}
numItems--;
}
else
{
throw new ListIndexOutOfBoundsException(
"ListIndexOutOfBoundsException on remove");
}
}
Make sure that unused items elements are set to null otherwise objects referenced from there cannot be garbage collected.
After the for loop shifting down the items add a line:
items[numItems-1] = null;
Structure of my class:
public class Priorityy implement Comparable {
public int compareTo(Object pe) {
Priorityy p = (Priorityy) pe;
if (this.key < p.key) {
return 1;
} else if (this.key > p.key) {
return -1;
} else {
return 0;
}
}
}
Th problem is that p.key is always null, why exactly is that? I have my array initialized with elements in it but it always throws NullPointerException whenever I try Arrays.sort(arr).
How can I fix this?
Edit: Here is the complete code and print did print the elements of array arr:
import java.util.Arrays;
class Priorityy implements Comparable {
int size;
int front = 0;
int rear = 0;
static Priorityy[] arr = new Priorityy[3];
int key;
String value;
public Priorityy(int key, String value) {
this.key = key;
this.value = value;
insert();
}
public void insert() {
arr[front] = this;
System.out.println(arr[front].value);
while (front + 1 != 3) {
front = front + 1;
}
}
public Priorityy remove() {
Priorityy x = arr[front];
front = front - 1;
return x;
}
public int compareTo(Object pe) {
Priorityy p = (Priorityy) pe;
if (this.key < p.key) {
System.out.println(p.key);
return 1;
} else if (this.key > p.key) {
System.out.println("3");
return -1;
} else {
System.out.println("4");
return 0;
}
}
public static void main(String... s) {
new Priorityy(10, "Watch");
new Priorityy(40, "Laptop");
new Priorityy(60, "Wallet");
Arrays.sort(arr);
for (Priorityy element : arr) {
System.out.println(element.key);
System.out.println(element.value);
}
}
}
As per your code
Priorityy p = (Priorityy)pe;
^^ ---------- this is null
You have null object in the array. Handle null object gracefully.
For example
if(pe instanceof Priorityy){ // return false for null object
// your code goes here
}
Better use Generic Comparable and use Integer.compare(int,int) to compare two int values.
class Priorityy implements Comparable<Priorityy> {
public int compareTo(Priorityy pe) {
if (pe != null) {
return Integer.compare(this.key, pe.key);
} else {
// return what ever if pe is null
}
}
}
You're putting things into your array in a really strange manner.
But given that, the problem is that you're not using a static field to store the next position to insert an element into, so the next time you create an instance of Priorityy, the field first contains the value zero again. So you're inserting all three objects into element zero of the array.
Change one line of your code and it will work:
int front = 0;
To:
static int front = 0;
I don't see where you are using size and rear but you probably want these to be static too.
One other suggestion: Java has a nice short syntax for increasing or decreasing the value of a variable by one using the ++ or -- operator, so you can shorten things by saying:
front++;
instead of
front = front + 1;
(and front-- instead of front = front - 1)
Using binarySearch never returns the right index
int j = Arrays.binarySearch(keys,key);
where keys is type String[] and key is type String
I read something about needing to sort the Array, but how do I even do that if that is the case?
Given all this I really just need to know:
How do you search for a String in an array of Strings (less than 1000) then?
From Wikipedia:
"In computer science, a binary search is an algorithm for locating the position of an element in a sorted list by checking the middle, eliminating half of the list from consideration, and then performing the search on the remaining half.[1][2] If the middle element is equal to the sought value, then the position has been found; otherwise, the upper half or lower half is chosen for search based on whether the element is greater than or less than the middle element."
So the prerequisite for binary search is that the data is sorted. It has to be sorted because it cuts the array in half and looks at the middle element. If the middle element is what it is looking for it is done. If the middle element is larger it takes the lower half of the array. If the middle element is smaller it the upper half of the array. Then the process is repeated (look in the middle etc...) until the element is found (or not).
If the data isn't sorted the algorithm cannot work.
So you would do something like:
final String[] data;
final int index;
data = new String[] { /* init the elements here or however you want to do it */ };
Collections.sort(data);
index = Arrays.binarySearch(data, value);
or, if you do not want to sort it do a linear search:
int index = -1; // not found
for(int i = 0; i < data.length; i++)
{
if(data[i].equals(value))
{
index = i;
break; // stop looking
}
}
And for completeness here are some variations with the full method:
// strict one - disallow nulls for everything
public <T> static int linearSearch(final T[] data, final T value)
{
int index;
if(data == null)
{
throw new IllegalArgumentException("data cannot be null");
}
if(value == null)
{
throw new IllegalArgumentException("value cannot be null");
}
index = -1;
for(int i = 0; i < data.length; i++)
{
if(data[i] == null)
{
throw new IllegalArgumentException("data[" + i + "] cannot be null");
}
if(data[i].equals(value))
{
index = i;
break; // stop looking
}
}
return (index);
}
// allow null for everything
public static <T> int linearSearch(final T[] data, final T value)
{
int index;
index = -1;
if(data != null)
{
for(int i = 0; i < data.length; i++)
{
if(value == null)
{
if(data[i] == null)
{
index = i;
break;
}
}
else
{
if(value.equals(data[i]))
{
index = i;
break; // stop looking
}
}
}
}
return (index);
}
You can fill in the other variations, like not allowing a null data array, or not allowing null in the value, or not allowing null in the array. :-)
Based on the comments this is also the same as the permissive one, and since you are not writing most of the code it would be better than the version above. If you want it to be paranoid and not allow null for anything you are stuck with the paranoid version above (and this version is basically as fast as the other version since the overhead of the method call (asList) probably goes away at runtime).
public static <T> int linearSearch(final T[] data, final T value)
{
final int index;
if(data == null)
{
index = -1;
}
else
{
final List<T> list;
list = Arrays.asList(data);
index = list.indexOf(value);
}
return (index);
}
java.util.Arrays.sort(myArray);
That's how binarySearch is designed to work - it assumes sorting so that it can find faster.
If you just want to find something in a list in O(n) time, don't use BinarySearch, use indexOf. All other implementations of this algorithm posted on this page are wrong because they fail when the array contains nulls, or when the item is not present.
public static int indexOf(final Object[] array, final Object objectToFind, int startIndex) {
if (array == null) {
return -1;
}
if (startIndex < 0) {
startIndex = 0;
}
if (objectToFind == null) {
for (int i = startIndex; i < array.length; i++) {
if (array[i] == null) {
return i;
}
}
} else {
for (int i = startIndex; i < array.length; i++) {
if (objectToFind.equals(array[i])) {
return i;
}
}
}
return -1;
}
To respond correctly to you question as you have put it. Use brute force
I hope it will help
public int find(String first[], int start, int end, String searchString){
int mid = start + (end-start)/2;
// start = 0;
if(first[mid].compareTo(searchString)==0){
return mid;
}
if(first[mid].compareTo(searchString)> 0){
return find(first, start, mid-1, searchString);
}else if(first[mid].compareTo(searchString)< 0){
return find(first, mid+1, end, searchString);
}
return -1;
}
Of all the overloaded versions of binarySearch in Java, there is no such a version which takes an argument of String. However, there are three types of binarySearch that might be helpful to your situation:
static int binarySearch(char[] a, char key);
static int binarySearch(Object[] a, Object key);
static int binarySearch(T[] a, T key, Comparator c)