Remove items from custom arraylist implemetation without .remove - java

I'm working on a custom ArrayList implementation and I have one method where I'm trying to remove an item per conditions from an array such as E[] elements. The array is initialized by doing something like this:
String[] contents = {"chicken", "hippo", "goat"};
ArrayI<String> newarray = new ArrayI(contents);
newarray.chooser(new LongChooser());
It should remove words length 4 or less and return an array like this:
["chicken", "hippo"]
I'm trying not to use any built in methods, like remove(), clone(), arraycopy(), etc. I can't seem to get this to work, I've tried creating a duplicate array and trying to copy elements over like this:
E[] copy = (E[]) (new Object[this.size-1]);
for (int i = 0; i < size; i++) {
if (shorter) {
copy[i] = elements[i];
}
else {
for (int j = i; j<this.size-1; j++) {
elements[j] = elements[j+1];
}
elements[size-1] = null;
size -= 1;
}
for (int i =0; i< copy.length; i++) {
elements[i] = copy[i];
}
size -= 1;
I know this is not the correct way because they aren't the same size array and just returns [longword, longerword, null]. Also I'm pretty sure I should be using the size variable, but it doesn't seem to do much.
How do I get this to work? Thanks.

Create an array to hold the [filtered] results. Its initial size is zero.
Iterate through contents.
If the current element of contents needs to be retained, then
create a temporary array whose length is one greater than the array that holds the results.
copy the results array to the temporary array
set the last element of the temporary array to the current element of contents
assign the temporary array to the results array
Here is the code, using only simple arrays. I presume you can adapt it to your needs. Note that the last line is simply to check the value of newContents. It is not required.
String[] contents = {"chicken", "hippo", "goat"};
String[] newContents = new String[0];
for (String str : contents) {
if (str.length() > 4) {
String[] temp = new String[newContents.length + 1];
for (int i = 0; i < newContents.length; i++) {
temp[i] = newContents[i];
}
temp[newContents.length] = str;
newContents = temp;
}
}
System.out.println(Arrays.toString(newContents));

Related

Removing items from custom arraylist implementation

I'm working on a custom Arraylist implementation and I have one method where I'm trying to remove an item per conditions from an array such as E[] elements. The array is initialized by doing something like this:
String[] contents = {"chicken", "hippo", "goat"};
ArrayI<String> newarray = new ArrayI(contents);
newarray.chooser(new LongChooser());
It should remove words length 4 or less and return an array like this:
["chicken", "hippo"]
I'm trying not to use any built in methods, like remove(), clone(), arraycopy(), etc. I can't seem to get this to work, I've tried creating a duplicate array and trying to copy elements over like this:
E[] copy = (E[]) (new Object[this.size-1]);
for (int i = 0; i < size; i++) {
if (shorter) {
copy[i] = elements[i];
}
else {
for (int j = i; j<this.size-1; j++) {
elements[j] = elements[j+1];
}
elements[size-1] = null;
size -= 1;
}
for (int i =0; i< copy.length; i++) {
elements[i] = copy[i];
}
size -=1;
I know this is not the correct way because they aren't the same size array and just returns [longword, longerword, null]. Also I'm pretty sure I should be using the size variable, but it doesn't seem to do much.
How do I get this to work? Thanks.

How do I combine the first element of 2 array together into a string array?

String quantityArray[] = GetStringArray(quantity);
String foodItemArray[] = GetStringArray(fooditems);
this is to change from ArrayList to a String Array
int n1 = fooditems.size();
int n2 = quantity.size();
for(int s = 0; s<n1;s++){
totalFood[s] = quantityArray[s] + foodItemArray[s];
}
I cannot make this totalFood[] function to work as it just keeps crashing my app
public static String[] GetStringArray(ArrayList<String> arr) {
// declaration and initialise String Array
String str[] = new String[arr.size()];
// ArrayList to Array Conversion
for (int j = 0; j < arr.size(); j++) {
// Assign each value to String array
str[j] = arr.get(j);
}
return str;
}
The error that pops up is (Attempt to write to null array)
You need to make sure totalFood array is allocated.
Arrays are themselves Objects in Java.
For example:
totalFood = new String[n1];
This is because totalFood seems to be null according to the error you are seeing. You need to allocate some space (n1 references to be precise for the above example) for the Strings resulting from the concatenation to be stored at. You can take a look at the corresponding Java tutorial here.
Also make sure n1 is equal to n2 which should be equal also to the size of the totalFood array in order to not overrun any of them in your loop.
Finally, there are 2 handy Collection#toArray methods which will do what you are doing in your GetStringArray method. You can use it for example like so:
String quantityArray[] = quantity.toArray(new String[quantity.size()]);
Using the toArray method seems not to be related to the problem, but I just mention it for completeness.
public static String[] GetStringArray(ArrayList<String> arr) {
String str[] = new String[arr.size()];
for (int j = 0; j < arr.size(); j++) {
str[j] = arr.get(j);
}
return Arrays.stream(str).filter(s -> s!=null).toArray(String[]::new);
}

Suggestions for my Selection Sort / Java

My Selection Sort algorithm is not working.
I am getting the following errors:
//Exception in thread "main" java.lang.NullPointerException
Note: this is for a java class. I do not have a lot of experience. I am done with the assignment. I am trying to understand the reason why my sorting algorithm isn't working.
Any suggestions on how to correct the problem? Tips?
Corrections? ... any help at all will be appreciated.
Here is my code:
private void sortFlowers(String flowerPack[]) {
// TODO: Sort the flowers in the pack (No need to display them here) - Use Selection or Insertion sorts
// NOTE: Special care is needed when dealing with strings! research the compareTo() method with strings
for(int i = 0; i < flowerPack.length; i++){
String currentMinFlow = flowerPack[i];
int minIndex = i;
for(int j = i; j < flowerPack.length; j++){
if(currentMinFlow.compareToIgnoreCase(flowerPack[j]) <0){
currentMinFlow = flowerPack[j];
minIndex = j;
}
}
if(minIndex != i){
flowerPack[minIndex] = flowerPack[i];
flowerPack[i] = currentMinFlow;
}
}
}
Exception:
Exception in thread "main" java.lang.NullPointerException at
java.lang.String$CaseInsensitiveComparator.compare(String.java:1181) at
java.lang.String$CaseInsensitiveComparator.compare(String.java:1174) at
java.lang.String.compareToIgnoreCase(String.java:1227) at
Assignment01Driver.sortFlowers(Assignment01Driver.java:112) at
Assignment01Driver.<init>(Assignment01Driver.java:37) at
Assignment01Driver.main(Assignment01Driver.java:5)
The issue is coming from the fact that your array was created with a fixed size.
String[] flowerPack = new String[25];
When you create an array of reference type variables, each variable will be initialized with a value of null. If you call the sortFlowers method before each variable is given a value, you run into an issue.
for(int i = 0; i < flowerPack.length; i++){
String currentMinFlow = flowerPack[i];
In the above segment, you are iterating through all 25 positions in the array, including the values that still have a value of null. Then, the following line causes the error:
if(currentMinFlow.compareToIgnoreCase(flowerPack[j]) <0){
Since you are iterating through the entire array, you end up with values of currentMinFlow that are null. If you try to make a method call on a null reference value, you end up with a NullPointerException.
Generally, you rarely want to use fixed size arrays when you're unsure of how many data items you're likely to have. In this case, you would want to use an ArrayList in place of a standard array. An ArrayList is essentially a dynamic array that grows and shrinks as necessary to contain the elements you store in it. This will get rid of your problem with null values, since this will prevent you from having any unused elements in your array.
Replace
String[] flowerPack = new String[25];
with
ArrayList<String> flowerPack = new ArrayList<>();
If you wanted to add or remove a value from the ArrayList you could do
// Add value.
flowerPack.add(value);
// Remove value
flowerPack.remove(value);
If you want to access a certain element in the ArrayList:
String element = flowerPack.get(indexOfElement);
If you want to get the size of the ArrayList:
int size = flowerPack.size();
And if you don't want to modify your sorting method, you can keep it the same by replacing the line
sortFlowers(flowerPack);
with
sortFlowers(flowerPack.toArray(new String[0]));
For an overview of other ArrayList methods and properties, check the online documentation:
https://docs.oracle.com/javase/8/docs/api/java/util/ArrayList.html
The error says that you are trying to deal with the array that holds a value of null. to understand better, fill in all 25 spots in the array and run the program, it will not give you any error.
Here is the solution that you need.
private void sortFlowers(String flowerPack[])
{
//get the length of the array by counting arrays where the value is not null.
int length = 0;
for (int i = 0; i < flowerPack.length; i++)
{
if (flowerPack[i] != null)
{
length = length + 1;
}
}
//just confirm that the count is correct.
System.out.println(length);
//set the length to the "length" variable as we have found above.
for(int i = 0; i < length; i++)
{
String currentMinFlow = flowerPack[i];
int minIndex = i;
for(int j = i; j < length;j++){
if(currentMinFlow.compareToIgnoreCase(flowerPack[j]) <0)
{
currentMinFlow = flowerPack[j];
minIndex = j;
}
}
if(minIndex != i){
flowerPack[minIndex] = flowerPack[i];
flowerPack[i] = currentMinFlow;
}
}
}
Just replace your sortFlowers method with above code and check.

Appending to double Array method

So, I have a method like this
public String[][] getArgs(){
And, I want it to get results out of a for loop:
for(int i = 0; i < length; i++){
But how do I append them to the array instead of just returning them?
Create a String[][] array inside your method, fill this array inside a loop (or in any other way) and return that array in the end.
If you are sure you want to have only one for loop (instead of two, typical for 2-dimensional array), ensure your loop will go through the number of examples equal to the number of fields in your String[][] array. Then you can calculate the double-dimension array indexes from your single loop-iterator, for example:
for(int i = 0; i < length; i++){
int a = i % numberOfCollumnsInOutput;
int b = i / numberOfCollumnsInOutput;
String[a][b] = sourceForYourData[i];
}
(Of course which array dimension you treat as collumns (and which to be rows) depends on yourself only.) However, it is much more typical to go through an n-dimensional array using n nested loops, like this (example for 2d array, like the one you want to output):
for(int i = 0; i < dimensionOne; i++){
for(int j = 0; j < dimensionTwo; j++){
array[i][j] = someData;
}
}
For your interest. A sample code according to Byakuya.
public String[][] getArgs(){
int row = 3;
int column =4;
String [][] args = new String[row][column];
for(int i=0;i<row;i++)
for(int j=0;j<column;j++)
args[i][j] = "*";
return args;
}
You can make a LinkedList from that array, and then append the elements to it, and then create a new array from it. If you are not sure i'll post some code.

Removing duplicates in an Array-based unsorted list without sets

Consider the operation removeAll, which removes all occurrences of element from a list.
The method returns the number of elements removed.
public int removeAll(E element)
Implement this operation for:
1. Array-based unsorted list
we cant use sets.
What i have started for now:
public int removeAll(T element) {
int duplicatesRemoved = 0;
for (int i = 0; i <= array.length - 1; i++) {
for (int j = i + 1; j <= array.length - 1; j++) {
if (array[i] == array[j]) {
}
}
I'm unable to get the rest done, any help please?
Dump the contents in a collection of some sort since you're not allowed to use Set, then pull out what's in the collection.
Arrays (the class, not primitive arrays) support a contains method, but you'll be iterating over the new collection everytime, making it inefficient.
Or if you can't use Array either, you can do it in a primitive array, just walking through looking for duplicates, over and over.
I suggest that you set the duplicate elements to something like null. After you've removed all duplicates, compact the array by swapping non-null elements at the end with the null elements in the middle.
Alternatively, create an empty array, and move non-duplicate elements to the new array.
Short answer
Use a Map.
More answer
Here is an algorithm, it is functional, but can be improved:
Create a Map<T, Boolean>. The second parameter type is whatever you want, I chose Boolean.
Create a new array named newArray; this will contain the unique values.
Iterate through the array. For each item perform the following:
Using the current arrayValue as the key, get the storedValue from the map.
if the storedValue is null (i.e. the Map.get() returned null) then this is a unique item. Insert the arrayValue, Boolean.TRUE into the map and add the arrayValue to the newArray.
if the storedValue is not null, then increment the duplicate count.
After iterating through the list, the newArray contains all non-duplicates and the duplicate count contains the count of duplicates.
1.
/**
* This method removes all duplicates from an array named "array"
* using a temporary List. So it converts the array into
* something like a Java set
*
* #return int number of duplicates removed
*/
public static int removeAll() {
int duplicates = 0;
List<Object> list = new ArrayList<>();
for(int i=0;i<array.length;i++){
Object element = array[i];
if(list.contains(element)) {
duplicates++;
}
else {
list.add(element);
}
}
array = list.toArray();
return duplicates;
}
2.
/**
* This method removes duplicates from an array named "array" using a
* temporary List.
* #param elementToBeRemoved
* #return int number of duplicates removed
*/
public static int removeAll(Object elementToBeRemoved) {
int duplicates = 0;
List<Object> list = new ArrayList<>();
for (int i = 0; i < array.length; i++) {
Object element = array[i];
if (list.contains(elementToBeRemoved)) {
duplicates++;
} else {
list.add(element);
}
}
array = list.toArray();
return duplicates;
}
As this seems homework, no explanation, but this puzzle:
int lengthWithValues = array.length;
for (int i = 0; i < lengthWithValues; i++) {
// Loop invariant: for all at < i array is sorted, unique and complete.
int valueToBeChecked = array[i];
for (int k = i + 1, int j = i + 1; k < lengthWithValues; j++) {
if (array[j] == valueToBeChecked) {
--lengthWithValues; // Remove duplicate
} else {
array[k] = array[j]; // Maintain differing from all at <= i.
++k;
}
}
}
duplicatesRemoved = array.length - lengthWithValues;
// array[0 .. length - duplicatesRemoved] is the unique array.
int[] uniqueArray = new int[lengthWithValues];
System.arrayCopy(array, 0, uniqueArray, 0, lengthWithValues);

Categories