I would like to add an object to an array and return true if the array is not full so the item can be added, and false if the array is full of items.
What I have right now I believe is only partially correct.
private Object[] theList;
//constructors omitted
#Override
public boolean add(Object toAdd) {
for(int i=0; i < theList.length;i++){
if(toAdd != null){
theList[i] = toAdd;
}
}
return true;
}
I think using an element counter would be the right way to go to keep track
of the number of element currently in the array.
The method is overridden from an interface, if that matters.
Not sure if it is returning true based on the on the loop and conditions or just returning true no matter what.
It looks like you're trying to find the first null value in your array, and if such a value exists, replace it with your toAdd object and return true.
The code for that would be something along the lines of:
private Object[] theList;
#Override
public boolean add(Object toAdd) {
for(int i=0; i < theList.length; i++) {
if(theList[i] == null){
theList[i] = toAdd;
return true;
}
}
return false;
}
If you also want to return false in case your toAdd object is null, for performance reasons, you should check for that before looping over the array:
#Override
public boolean add(Object toAdd) {
if (toAdd != null) {
for(int i=0; i < theList.length; i++) {
if(theList[i] == null){
theList[i] = toAdd;
return true;
}
}
}
return false;
}
Obviously it's more convenient to use an ArrayList instead.
You Have not initialized Your object[] ObjectArray theList. So, It won't be able to add new element to this.
Here I am Giving a Solution For Your Problem Using ArrayList Class. ArrayList is an auto Growable Array Increased Its Size Dynamically at Runtime.
private ArrayList<Object> theList = new ArrayList<>(); //A Auto Growable Array Increased Its Size Dynamically at Runtime.
//constructors omitted
#Override
public boolean add(Object toAdd) {
if(toAdd != null){
theList.add(toAdd);
return true; //returns true id Object is added to theList.
}else
return false; //returns false if Object is Null .
}
Code to Get ArrayList Size
theList.size() //Use This Code to know the Size of Array List.
First of all you have to initialize the array. Otherwise it will return you a Null Pointer Exception. Here is my code. Hope it will help...
class Demo{
static boolean result;
public static void main(String args[]){
Object ob= new Object();
result = A.add(ob);
System.out.println(result);
Object ob1= new Object();
result = A.add(ob1);
System.out.println(result);
}
}
class A{
static private Object[] theList = new Object[10];
public static boolean add(Object ob){
boolean result = false;
for(int i=0; i<theList.length; i++){
if(ob != null){
theList[i] = ob;
result = true;
}
}
return result;
}
}
Default value of array of objects is null. So that you can check whether an element is null or not.
for(int i=0:i<theList.length;i++) {
if(theList[i] == null && toAdd!=null) // Element is null or not
theList[i]=toAdd;
return true;
}
return false;
if element is null then array is still empty and you can put value there and return true.
You may want to consider using an ArrayList as they are expandable and do not have a set size. So whenever you add something it just grows the ArrayList instead of changing the value of an index.
Edited second time, another solution as per suggestions by peer contributers. I have also posted understanding of the questions in the comments. Please suggest if there is any aberration in the understanding.
Kindly see one possible solution:
public class TestCode {
public static void main(String[] args) {
/*
* Question:
* I would like to add an object to an array and
* return true if the array is not full so the item can be added,
* and false if the array is full of items.
*/
Object[] objects = new Object [] {1, 2, null, 4, 5, null , 7};
SomeClass someClass = new SomeClass(objects);
// just for sake of passing;
Integer toAdd = 10;
boolean isNotFull = someClass.add(toAdd);
System.out.println("Array after adding: "+Arrays.toString(objects));
System.out.println("Array is Not full:"+isNotFull);
isNotFull = someClass.add(toAdd);
System.out.println("Array after adding: "+Arrays.toString(objects));
System.out.println("Array is Not full:"+isNotFull);
isNotFull = someClass.add(toAdd);
System.out.println("Array after adding: "+Arrays.toString(objects));
System.out.println("Array is Not full:"+isNotFull);
}
}
class SomeClass {
private Object[] theList;
//constructors omitted
public SomeClass(Object[] theList) {
this.theList = theList;
}
/*
* returns true if array is not full and element is inserted.
*/
public boolean add(Object toAdd) {
int i = 0;
boolean flag = false; // if flag is true, the array is not empty
// question says:
// "I would like to add an object to an array"
// means we need to first find an empty slot to insert in the array
for( ; i < theList.length;i++){
// to check if there is any first empty space in the array
// so that the element can be inserted.
// (finding the empty slot
if(theList[i] == null){
// to check if elements passed as an aargument itself is false
if (toAdd!=null) {
theList[i] = toAdd;
break;
}
}
}
for (;i <theList.length; i++) {
if(theList[i] == null){
flag = true;
}
}
return flag;
}
}
Solution:
Output of the code as I get:
Array after adding: [1, 2, 10, 4, 5, null, 7]
Array is Not full:true
Array after adding: [1, 2, 10, 4, 5, 10, 7]
Array is Not full:false
Array after adding: [1, 2, 10, 4, 5, 10, 7]
Array is Not full:false
Related
I'm creating a resizeable Object Array. Below is my add function in which I pass through the object I want to add into my arraylist.
The function works, however if someone could explain this code
temp[theList.length] = toAdd;
I understand that it's adding the parameter argument to the end of the new Arraylist. But what's confusing me is the index that I pass into temp[]. Shouldn't I be including theList.length + 1 rather than just theList.length?
public boolean add(Object toAdd) {
if (toAdd != null) {
Object[] temp = new Object[theList.length + 1];
for (int i = 0; i < theList.length; i++) {
temp[i] = theList[i];
}
temp[theList.length] = toAdd;
theList = temp;
return true;
} else {
System.out.println("Invalid type");
return false;
}
}
Explanation for the add method:
Assume, the size of the theList is 10.
They have created an temp array which takes size as theList + 1, so size of temp is 11.
Now, objects are added to the temp except for the last element tem[10].
For adding the last element, you can use any of the 2 ways:
temp[theList.length] //temp[10]
Or
temp[temp.length-1] //temp[10]
They used the 1st way to add the toAdd object.
You could use a standard method Arrays.copyOf which immediately creates a copy of the input array with the new size (in this case, the length is increased):
import java.util.Arrays;
//...
public boolean add(Object toAdd) {
if (toAdd != null) {
int oldLength = theList.length;
theList = Arrays.copyOf(theList, oldLength + 1);
theList[oldLength] = toAdd;
return true;
} else {
System.out.println("Cannot add null object");
return false;
}
}
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);
}
}
}
I know references to objects in java are passed by copy , but the copy still points to the same memory in system , so after updating some data of the complex object in another function , the original data should me maintained. But interestingly something is going wrong here. I am working with Tries.
Here is my implementation of Trie, it's fairly custom implementation because of some custom rules:
public class Trie {
boolean isEnd;
Trie trie[] = new Trie[256];
ArrayList<Integer> indexNode;
public static Trie createTrieNode() {
Trie temp = new Trie();
temp.isEnd = false;
temp.indexNode = new ArrayList<Integer>();
for (int i = 0; i < temp.trie.length; i++) {
temp.trie[i] = null;
}
return temp;
}
public static void insertIntoTrie(Trie root, char[] alpha, int index, int i) {
if (root == null)
root = createTrieNode();
if (i < alpha.length)
insertIntoTrie(root.trie[alpha[i] - 'a'], alpha, index, i + 1);
else {
if (root.isEnd == true) {
root.indexNode.add(index);
} else {
root.isEnd = true;
root.indexNode.add(index);
}
}
}
}
Now my object root comes from this class and In the debugger I can see this statement being executed : root.isEnd = true;
Class:
public class AnagramsTogether {
public Trie root = new Trie();
public void printAnagrams(String[] anagrams){
char[] buffer;
for (int i = 0; i < anagrams.length; i++) {
buffer = anagrams[i].toCharArray();
Arrays.sort(buffer);
Trie.insertIntoTrie(root, buffer, i, 0);
}
AnagramsUtil.anagramUtil(root,anagrams);
}
}
But when when root is passed here AnagramsUtil.anagramUtil(root,anagrams);
public class AnagramsUtil {
public static void anagramUtil(Trie root, String[] anagrams) {
if (root.isEnd == true) {
for (Iterator<Integer> iterator = root.indexNode.iterator(); iterator
.hasNext();) {
Integer integer = (Integer) iterator.next();
System.out.println(anagrams[integer]);
}
} else {
for (int i = 0; i < root.trie.length; i++) {
if (root.trie[i] == null)
continue;
anagramUtil(root.trie[i], anagrams);
}
}
}
}
public class Anagram{
public static String string[] = {"cat", "dog", "god","act", "tac","gdo"};
public static void main(String args){
new AnagramsTogether().printAnagrams(Anagram.string);
}
}
This statement if (root.isEnd == true) in never executed and so is this is never executed anagramUtil(root.trie[i], anagrams); . The program just keep executing the continue statement.
Which should not be the case as I've already seen root.trie[i] receiving values.
Why does this happen?I am fairly new to java.
You have many Trie objects in your program and you are confusing them. If you check object identity (object number) with your debugger, you will see that they are not the same.
You are saying that you see in the debugger the statement root.isEnd = true; to be executed however you don't mention for which object is executing.
Your insertIntoTrie() method is called recursively so, that statement is probably executed for the Trie objects that the root has in its trie[] array but not for the root object itself.
Since the actual execution depends on the arguments you are using to call printAnagrams(String[] anagrams) please add those to your question if you need a more specific answer.
Update: Ok after you have edited your question it is clear that you are making the mistake to misuse object references even though you know that all "...references to objects in java are passed by copy". Your insertIntoTrie() is faulty. It seems that you intend to create a new object if the argument root is null however that new object will be lost because root argument is a copy. At the end of your method if you print the whole trie[] member of your original root object (the one in the AnagramsTogether class) you will see that all objects are null.
In Java, null is not an object, it is only a special type. Therefore null hasn't got a reference. So that, for example:
Trie root = null;
insertIntoTrie(root, alpha, index, i);
// after called this function, root = null
After called this function, root is still null because the variable root isn't yet an object before calling this function. So that there wasn't any reference of the variable root to be passed by copy in this calling.
Solution:
Change your function:
public static void insertIntoTrie(Trie root, char[] alpha, int index, int i) {
if (root == null)
root = createTrieNode();
if (i < alpha.length)
insertIntoTrie(root.trie[alpha[i] - 'a'], alpha, index, i + 1);
else {
if (root.isEnd == true) {
root.indexNode.add(index);
} else {
root.isEnd = true;
root.indexNode.add(index);
}
}
}
Into :
public static void insertIntoTrie(Trie root, char[] alpha, int index, int i) {
if (i < alpha.length) {
if (root.trie[alpha[i] - 'a'] == null) {
root.trie[alpha[i] - 'a'] = createTrieNode();
}
insertIntoTrie(root.trie[alpha[i] - 'a'], alpha, index, i + 1);
}
else {
if (root.isEnd == true) {
root.indexNode.add(index);
} else {
root.isEnd = true;
root.indexNode.add(index);
}
}
}
This solution make sure that the root is always an object before passing to the insertIntoTrie(...) function.
I´m trying to find similar rows in multiple two-dimensional arrays as it was described in my previous post. For the below-given example, the answer is false, true, although it should be false, false.
Another very important question is how to adjust this code to arrays with the different number of rows.
I appreciate very much any help. Thanks.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class Test {
public static void main(String[] args) {
ArrayList<Integer[]> array1 = new ArrayList<Integer[]>();
ArrayList<Integer[]> array2 = new ArrayList<Integer[]>();
ArrayList<Integer[]> array3 = new ArrayList<Integer[]>();
array1.add(new Integer[]{1,2,3}); array1.add(new Integer[]{1,0,3});
array2.add(new Integer[]{1,0,3}); array2.add(new Integer[]{0,0,3});
array3.add(new Integer[]{1,2,3}); array3.add(new Integer[]{0,3,3});
for (int i=0; i<array1.size(); i++) {
boolean answ = equalRows(array1.get(i),array2.get(i),array3.get(i));
System.out.println(answ);
}
}
static class Row extends Object {
private int value;
public Row(int val) {
this.value = val;
}
#Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if((obj == null) || (obj.getClass() != this.getClass()))
return false;
// object must be Row at this point
Row row = (Row)obj;
return (value == row.value);
}
#Override
public int hashCode () {
return this.value;
}
}
private static Map<Row, Integer> map(Integer[] row) {
Map<Row, Integer> rowMap = new HashMap<Row, Integer>();
for (int i=0; i<row.length; i++)
rowMap.put(new Row(row[i]), i);
return rowMap;
}
private static boolean equalRows(Integer[] row1, Integer[] row2, Integer[] row3){
Map<Row, Integer> map1 = map(row1);
Map<Row, Integer> map2 = map(row2);
for (int i=0; i<row3.length; i++){
Row row = new Row(row3[i]);
Integer result1 = map1.get(row);
Integer result2 = map2.get(row);
if (result1 == null || result2 == null) {
return false;
}
}
return true;
}
}
Edit#1
In the first test I´m comparing {1,2,3}, {1,0,3} and {1,2,3}. In the second: {1,0,3}, {0,0,3}, {0,3,3}. The problem with the second row is that {0,0,3} and {0,3,3} are tackled as {0,3}. I don´t know how to modify the code to deferentiate between {0,0,3} and {0,3,3} (I still should use HashMap).
Edit#2
The idea is that first I take rows from array1 and array2 and I put them into maps. Then I take a row from array3 and try to find it in maps. If I can´t find it in any of these maps, then it means that rows are not similar.
To compare two arrays, ignoring nulls you can have
public static <T> boolean equalsExceptForNulls(T[] ts1, T[] ts2) {
if (ts1.length != ts2.length) return false;
for(int i = 0; i < ts1.length; i++) {
T t1 = ts1[i], t2 = ts2[i];
if (t1 != null && t2 != null && !t1.equals(t2))
return false;
}
return true;
}
public static <T> boolean equalsExceptForNulls3(T[] ts1, T[] ts2, T[] ts3) {
return equalsExceptForNulls(ts1, ts2) &&
equalsExceptForNulls(ts1, ts3) &&
equalsExceptForNulls(ts2, ts3);
}
// or generically
public static <T> boolean equalsExceptForNulls(T[]... tss) {
for(int i = 0; i < tss.length - 1; i++)
for(int j = i + 1; i < tss.length; j++)
if(!equalsExceptForNulls(tss[i], tss[j])
return false;
return true;
}
The problem you have is that array3 is being used to determine which rows to compare.
In the first test you are comparing rows 1,2,3 and the second test you are comparing rows 0 and 3. The first test should be false and the second should be true.
I found the issue by stepping through your code in a debugger. I suggest you do the same.
I would also use int[] instead of Integer[]
I'm not quite sure what you are trying to accomplish but could it be that your problem lies in the method
public boolean equals(Object obj) {
if(this == obj)
return true;
if((obj == null) || (obj.getClass() != this.getClass()))
return false;
// object must be Row at this point
Row row = (Row)obj;
return (value == row.value);
}
because with
if(this == obj)
for example you want to have an value comparison - But what you get using the "==" comperator is a comparison of two objects references ?
So maybe
if(this.equals(obj))
is what you want ?
Furthermore, have you tried to step through your code in debugging mode statement per statement ? I guess doiing so could locate your fault quickly ...
cheers :)
There is a basic problem with your approach which leads to this bug. You are using a map to determine the position of an element in the other rows. When constructing the map if there are duplicate elements in the rows, their previous indices will be overwitten. This is exactly what is happening in your case. There is a duplcate zero in the second row of second array.
here is what the maps look like for the second row
map1 = ((Row(1), 0), (Row(0), 1), (Row(3), 3))
map2 = ((Row(0), 1), (Row(3), 3))
Nnotice there are only two elements in map2 bcoz the first one was overwitten with the second one. When you do a lookup with the elements of the second row from the third array the lookup always succeeds (because it it looks only for a 0 and a 3 and never for a 1)
Moreover the condition you check for failure is incomplete i.e
if (result1 == null || result2 == null) {
return false;
}
should be
if (result1 == null || result2 == null || !result1.equals(i) || !result2.equals(i)) {
return false;
}
In my opinion you shouldn't be using a map at all. Instead compare each element one by one. To generalize the code for arrays of different lengths try using size() method of the ArrayList class.
If is important to you that a map should be used, then you should use the index of each array element as the key and the Row object as the value instead of doing the reverse.
sorry, just following on from the question I had here : here I am trying to run this method to remove a generic value (EltType) from a double sided queue(deque), but I keep getting an error in that, I call insertFirst twice, and insert the value "3" into the array twice, then, when I run removeFirst, it will print out "3" once, and then "Null" thereafter. Would anyone be able to help me out please ?
class ArrayBasedDeque<EltType> {
private final int CAPACITY = 10;
private int capacity;
private int end;
private EltType deque[];
public ArrayBasedDeque() {
this.capacity = CAPACITY;
deque = (EltType[]) (new Object[capacity]);
}
public EltType removeFirst() {
EltType[] tempArray;
EltType returned = deque[0];
tempArray = (EltType[]) new Object[capacity];
for (int i=1;i<capacity;i++) {
tempArray[i-1] = deque[i];
}
deque = tempArray;
return returned;
}
public boolean isEmpty() {
return end == 0;
}
public void insertFirst(EltType first) {
if(!isEmpty()) {
EltType[] tempArray;
tempArray = (EltType[]) new Object[capacity+1];
for (int i=0;i<deque.length;i++) {
tempArray[i+1] = deque[i];
}
deque = tempArray;
}
deque[0] = first;
}
}
Thank you :)
The big glaring issue is that end never changes. isEmpty() will always return true. Now let's look at your insertFirst() method.
public void insertFirst(EltType first) {
if(!isEmpty()) {
EltType[] tempArray;
tempArray = (EltType[]) new Object[capacity+1];
for (int i=0;i<deque.length;i++) {
tempArray[i+1] = deque[i];
}
deque = tempArray;
}
deque[0] = first;
}
Knowing that isEmpty() always returns true no matter what, what is the problem with this piece of code?
You need to update your end pointer too when you remove an element.
You should also investigate System.arrayCopy()