How can I make a dynamic array in Java? - java

Quick overview of our assignment:
User needs to enter grades received. We do not know how many grades user needs to enter. If the user enters "-1" thats when we know the user is done entering grades.
Problem is how do you use a counter and assign values to an array in the same loop? I would rather not have to ask the user to enter all values twice (Once to get array size and the second time to assign grades to index positions).
Our professor gave us a handout that tells us to basically guess the size of the array and hope for the best. I refuse to believe that's the only solution.
Any help would be appreciated. Thanks.

You can't make dynamic array in java.
For that you will have to use List or ArrayList.
We will have to provide the size of array before application run or at coding time, while arrayList gives us facility to add data while we need it, so it's size will automatically increased when we add data.
Example :
import java.util.*;
public class ArrayListDemo {
public static void main(String args[]) {
// create an array list
ArrayList al = new ArrayList();
System.out.println("Initial size of al: " + al.size());
// add elements to the array list
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
al.add(1, "A2");
System.out.println("Size of al after additions: " + al.size());
// display the array list
System.out.println("Contents of al: " + al);
// Remove elements from the array list
al.remove("F");
al.remove(2);
System.out.println("Size of al after deletions: " + al.size());
System.out.println("Contents of al: " + al);
}
}
this example is from here.
UPDATE :
When you define your list as:
List myList = new ArrayList();
you can only call methods and reference members that belong to List class. If you define it as:
ArrayList myList = new ArrayList();
you'll be able to invoke ArrayList specific methods and use ArrayList specific members in addition to those inherited from List.
List is not a class it is an interface. It doesn't have any methods implemented. So if you call a method on a List reference, you in fact calling the method of ArrayList in both cases.

Using some kind of List is a better choice, as it basically does what you want (can grow and shrink), in fact, ArrayList is just that, a dynamic array.
You can hand roll your own if you can't use a List using System.arraycopy
For example, this will grow or shrink an array to match the size you provide...
public String[] updateArray(String[] src, int size) {
String[] dest = new String[size];
if (size > src.length) {
System.arraycopy(src, 0, dest, 0, src.length);
} else {
System.arraycopy(src, 0, dest, 0, size);
}
return dest;
}
Again... List is easier...

Building a dynamic array involves these basic steps:
-Create an array of a fixed capacity.
-When the size of the array (# of elements added) approach the capacity, create a new array (usually doubling the capacity), and copy all the old elements to the new array.
A linked list is the most efficient for your task of building the array (done in O(1) time). However, accessing elements for inserting and deleting in a linked list is not efficient (O(n) time). Imagine having to move through the whole list to get to the last element. Building the dynamic array is less efficient, because of the need to re-size the array as it grows. Inserting and deleting elements is less efficient because of need to move all the elements after to make room or fill the gap. However accessing an element in an array is efficient (O(1) time) and there are big advantages when it comes to sorting.
The Java ArrayList is an implementation of a dynamic array. You could also implement your own.

If you can't use an ArrayList, or any kind of dynamic list at all, then one solution would be this:
StringBuilder sb = new StringBuilder();
Scanner scanner = new Scanner(System.in);
int j;
while((j=scanner.nextInt()) !=-1){
sb.append(j + " ");
}
String []numbers = sb.toString().split(" ");
int[] grades = new int[numbers.length];
for(int i=0;i<numbers.length;i++){
grades[i] = Integer.parseInt(numbers[i]);
}
As you can see, I'm putting the input in a stringbuilder object, then I parse it in an array of strings, and convert that array in an integer array.
I hope this helps.

Related

How can add an element to an array?

I wrote this code with a String array:
public static String[] prgmNameList = {"bbbbb", "aaaaa"};
My question is now, how can I add a new item to that array like this:
prgmNameList.add("cccc");
prgmNameList is an array. The size of an array object cannot be changed once it has been created. If you want a variable size container, use collections. For example, use an ArrayList :
List<String> prgmNameList = new ArrayList<String>(3);
prgmNameList.add("bbbb");
That said, if you insist on using an array, you will need to copy your initial array into a new array for each new element that you want to add to the array which can be expensive. See System#arrayCopy for more details. In fact, the ArrayList class internally uses an array that is expanded once it is full using System.arrayCopy so why reinvent the wheel? Just use an ArrayList
On simpler terms, note these following points:
Array size is always fixed.(In your example you fixed the array size to 2 by adding 2 elements)
Arrays operate based on index starting from '0' zero, like - prgmNameList[0] will return 1st element added in the array
Array size cannot be changed at any point of time. If you need size to be variable, choose one of List implementations
ArrayList is the best option for your need that can define itself as an 'Array that can shrink or grow'
Sample code:
public static List<String> prgmNameList= new ArrayList<String>();
prgmNameList.add("bbb");
prgmNameList.add("bbb");
prgmNameList.add("ccc");
prgmNameList.remove("bbb"); //Removes by object resolved by equals() method
prgmNameList.remove(2); //Removes by index
You have created an Array which can not grow as it's fixed in size.
You need to create a list in order to add new elements as shown below.
List<String> prgmNameList = new ArrayList<String>();
prgmNameList.add("aaaa");
prgmNameList.add("bbbb");
prgmNameList.add("cccc");
You have to use ArrayList like that
ArrayList<String> al = new ArrayList<>();
// add elements to the array list
al.add("C");
al.add("A");
al.add("E");
al.add("B");
if you want to use array as you did you have to know the number of elements that you want to add
String[] myList = new String[10];
and then
myList[4]="AA"
--
this is not possible to add to myList.
I explain you how ArrayList works and then you will understand.
ArrayList is an class that contains Array from objects. every time you add it check if it have place to store the data in the array if not it creates new array bigger and store the data.
So ArrayList this is the solution (or any other list)
if you want to add to myList you will have to implement arratList..
The method you are looking for is defined for a Collection, but you are using an array with an array initializer.
I suggest switching to the List:
public static List<String> prgmNameList= new ArrayList<>(Arrays.asList("bbbbb","aaaaa"))
Then you can call add on it because now it is a list.
Btw.: Try to prevent having mutable variables in static variables.

Growing array of primitives in java

I am learning Android and at the same time boosting my efficiency know-how. I am writing a password generator that generates a random password from a set of characters selected using specific rules. I have an array where I am planning to store the characters. The array begins at a size of X, which is the amount of possible character in all cases. I then add up to three times additional sets of characters to the array. Since I can't resize the array, I would have to copy and recreate it larger every time with a copy loop or ArrayCopy or similar.
Should I do that or switch to for example ArrayList? Sure, neither will in real life be problems as there will be about 70 characters in total, but I am interested in it as a practice.
Thanks to all.
pseudocode:
initialize array
add first set
if adding second set
add second set
if adding third set
add third set
if adding fourth set
add fourth set
return array
Switch to the collection (like your mentioned ArrayList), because it will be significantly more efficient then creating a new array and copying the values for every insert (which you must do if you use an array because, as you noted, arrays are statically sized at creation).
The ArrayList Javadoc says (in part),
Resizable-array implementation of the List interface. Implements all optional list operations, and permits all elements, including null. In addition to implementing the List interface, this class provides methods to manipulate the size of the array that is used internally to store the list.
Use ArrayList instead of a primitive array, then when you have all of the values in the ArrayList (which will grow) you can convert it to a primitive array like so:
List<Character> l = new ArrayList<Character>();
...
l.toArray();
You can use ArrayList as it is automatically resized when you add or remove items.
import java.util.*;
public class ArrayListDemo {
public static void main(String args[]) {
// create an array list
ArrayList al = new ArrayList();
System.out.println("Initial size of al: " + al.size());
// add elements to the array list
al.add("C");
al.add("A");
al.add("E");
al.add("B");
al.add("D");
al.add("F");
al.add(1, "A2");
System.out.println("Size of al after additions: " + al.size());
// display the array list
System.out.println("Contents of al: " + al);
// Remove elements from the array list
al.remove("F");
al.remove(2);
System.out.println("Size of al after deletions: " + al.size());
System.out.println("Contents of al: " + al);
}
}
Example taken from http://www.tutorialspoint.com/java/java_arraylist_class.htm

To print original array not sorted array

I am looking to print out my original unsorted array, I have it printing in order and sorted but I can't seem to get the original one to print out unsorted. I have used printRuleAndArray(String rule) and I have also used LengthCompare for the new sorted array, my problem is the original!!!
import java.util.*;
import java.util.Arrays;
// Example of how to sort an array
public class Sorting2
{
//declare an array of strings
static String[] nameArray = {"Alan", "Peter", "Ed", "Stephen", "Pheadraa"};
public static void main(String[] args)
{
// sorting by length
Arrays.sort(nameArray, new LengthCompare());
//print out elements of array
System.out.println(Arrays.toString(nameArray));
//count the number of elements in the array
int counter=nameArray.length;
//print out numeric number of elements in array
System.out.println("Number of elements in array: " + counter);
//print out sorted array with shortest first and longest last
printRuleAndArray("Sorted list by name length:");
}
Arrays.sort() will always sort the array you pass into it, it doesn't produce a fresh copy - so if you really need the unsorted array to hang around as well as the sorted array, then you'll have to make a copy of it:
String copyArr[] = new String[nameArray.length];
System.arraycopy( nameArray, 0, copyArr, 0, nameArray.length );
However, preferable to this approach (if feasible) would just be to do all the operations you need on the unsorted array (such as printing it or converting it to a string), then sort it afterwards.
As pointed out in the comment, Arrays.copyOf() could also be used to accomplish the same thing.
Arrays.sort will have altered your original array. Your choices are to either print your original array before sorting it, or to copy your original array and sort the copy.
Call String unsortedArr = Arrays.toString(nameArray); before array sorting, and when you need to print unsorted array just call System.out.println(unsortedArr);
Arrays.sort() sorts the array you pass into it. If you would like the original array later, copy the array first and then sort that array.
for(String arr : nameArray ) { //arr gets successively each value in nameArray.
System.out.println(arr);
}
this example is using foreach loop
Do something like this
String orig = Arrays.toString(nameArray);
Arrays.sort(nameArray, new LengthCompare());
String sorted = Arrays.toString(nameArray);
System.out.println(orig);
System.out.println(sorted);

Java: turning an arraylist into an array with an added element

I know that the code to turn an arraylist into an array is:
private String[] arrayLst_to_array(ArrayList<String> al) {
String[] arr = new String[al.size()];
arr = al.toArray(arr);
return arr;
}
But I want my new array to have a certain string in the beginning and then after that, I want the rest of the arraylist.
I know that I could just add the string that I want to the beginning of the arraylist and then convert it, but is there a more efficient way?
You can use System.arraycopy():
String[] arr = new String[al.size() + 1];
arr[0] = someStr; // initial string
// copy the list:
System.arraycopy(al.toArray(), 0, arr, 1, al.size());
return arr;
A memory efficient but maybe not so well performing solution would be:
public static String[] listPlusOne(final ArrayList<String> list, final String prepend)
{
final String[] arr = list.toArray(new String[list.size() + 1]);
System.arraycopy(arr, 0, arr, 1, list.size());
arr[0] = prepend;
return arr;
}
This solution allocates only one String array and performs a memory move using System.arrayCopy() to move all the elements one position up.
Generally speaking memory moving is always not the best solution. A LinkedList will allow pretty quick element prepending, but has O(n) complexity when accessing elements at random positions. The ArrayList is slower on prepending (memory moving, reallocation) but has O(1) when accessing elements.
So, either you use something like the code above, or you prepend the element to the list.
If you add an item to the beginning of the list, the contents of the entire list have to be moved one position up. This means each element is touched twice in the entire operation. If you export the list to an array and then use System.arrayCopy to make room for one in the beginning, again each item is touched twice.
The easiest solution that touches each item only once seems to be creating the array, adding the string, and then iterating over the list to add its elements.
String[] arr = new String[al.size() + 1];
arr[0] = someStr;
int i=1;
for (String s: al) {
arr[i++] = s;
}
Whether this is faster than the approaches that iterate over the items twice but benefit from the efficiency of System.arrayCopy should be shown by benchmarks.
In Short Answer to your question is No.The Option you gave i believe is the best way to do it.

How to find total number of different items within an arraylist.

I've done some searching but I wasn't able to find a valid solution. I have an arraylist storing Strings such as gum, socks, OJ, dog food...
I am having trouble iterating the list to determine the total number of differnt types of items.
ie.
ArrayList<String> Store = new ArrayList<String>();
this.Store.add("Gum");
this.Store.add("Gum");
this.Store.add("Socks");
this.Store.add("Candy");
The list has 4 total items, but only three different kinds of items (Gum, Sucks, Candy).
How would I design a method to calculate the 3?
What Bhesh Gurung said, but in code:
int numUnique = new HashSet<String>(Store).size();
If what you actually have is StoreItems and need to go through getName() then I would do
Set<String> itemNames = new HashSet<String>();
for (StoreItem item : Store)
itemNames.add(item.getName());
int numUnique = itemNames.size();
Use a Set (HashSet) whose size will give you what you are looking for.
This looks like a homework... So, if you do not understand the HashSet solution proposed above (or doning the same with a HashMap), think about doing something like this:
Create a new ArrayList
Take an element and check to see if it exists in the new ArrayList
If it is present in the new ArrayList, do nothing. Else add it.
Do this until you have examined the last element of the ArrayList.
Then, the size of the new array list should be the number you are looking for.
You can use the lastIndexOf method and loop through the arraylist.
char count=0;
for(char i=0; i<araylist.size(); i++){
if(i == araylist.lastIndexOf(araylist.get(i))){
count++;
}
}
Tested.

Categories