I've been undertaking some basic tutorials. One of which has asked me to set up an array to hold the following string values:
Beyonce (f)
David Bowie (m)
Elvis Costello (m)
Madonna (f)
Elton John (m)
Charles Aznavour (m)
Write a program to loop round, count how many are male vocalists and how many are female, and display my answer in the console.
I managed to complete it, but the way I set up my array was different to the answer provided.
Mine is as follows:
String names[] = {"Beyonce (f)", "David Bowie (m)", "Elvis Costello (m)", "Madonna (f)", "Elton John (m)", "Charles Aznavour (m)"};
And the provided answer is as such:
String[] singers = new String[6];
singers[0] = "Beyonce (f)";
singers[1] = "David Bowie (m)";
singers[2] = "Elvis Costello (m)";
singers[3] = "Madonna (f)";
singers[4] = "Elton John (m)";
singers[5] = "Charles Aznavour (m)";
Should I be creating a "new" array? If so, why? And what is the difference between the two?
Your answer is equivalent but more readable and less error-prone because you don't need any "magic numbers" for each array element with the "fear" of accessing an element out of the array definition and therefore creating an IndexOutOfBoundsException.
Both are doing the same thing.
First approach is more dynamic. You are telling java compiler that those elements will create an array. Compiler knows in compilation time their length, so it creates an array to fit them all.
In your second attepmt, you are first creating an array with length of 6. And then put in every slot one object.
When to use them:
If you know from the start what elements will be in the array, use first aproach - it is cleaner, shorter
But if there is some sort of logic that determined who should be placed in each slot, then second would be better. Like, when you want to create a 10 size array, but you will fill it during the runtime.
First aproach is also safer, because compiler created the array based on input length. Adding new element in code will change array size. In the second aproach you would have to change size manually, or ArrayOutOfBoundException will be thrown when adding singers[6].
But if you don't know the length of array (you will fill list in runtime), then you must use List or other dynamic structure (Set, List)
Both are valid ways to initialize an array.
Your way of initializing the array can only be done in the same expression that defines the array variable, though it can later be done in a similar way :
String[] names = null;
names = new String[] {"Beyonce (f)", "David Bowie (m)", "Elvis Costello (m)", "Madonna (f)", "Elton John (m)", "Charles Aznavour (m)"};
The provided answer explicitly creates an array of Strings, specifies the number of Strings that this array can store, and assigns values to the indices of the array.
Both solutions are correct. The first one uses an array initializer, the second one first instantiates the array and then populates it with values. One could argue that the first solution is more robust, since in the second solution the length of the array must be explicitly given before the entries are provided and it is possible to use indices beond the capacity of the array, which will be only detected at runtime.
A new array can be created with the new operator followed by the array element type and the array size between the [ ] characters - this is called the Array Creation Expression. Or when you declare a variable, you can also use an array literal which is called Array Initializers (but this cannot be used to assign a value to an array later on just when it is declared).
When you write
String names[] = {"A", "B", "C"};
It is just a short form and is equivalent to
String[] names = new String[] {"A", "B", "C"};
Note that to indicate that an array of the specified type is to be declared, both String[] names and String names[] forms can be used and they are equivalent, altough:
String names[], names2; // Only names is an array, names2 is just a String
While
String[] names, names2; // Both names and names2 are arrays!
It is recommended to use the second form to avoid confusion and accidents if later you add more variable names to the declaration.
Let's take a closer look of what happens in the 2 cases:
// "Slow" filling
String[] names = new String[3]; // Filled with null values by default
names[0] = "A"; // Explicit index, index range check!
names[1] = "B"; // Explicit index, index range check!
names[2] = "C"; // Explicit index, index range check!
// "Fast" filling at creation time, implicit indices and array length,
// No index checks!
String[] names = {"A", "B", "C"};
Advantages of creating and initializing the array in one step
There are several advantages of creating and initializing an array in one step:
Doing so is less error-prone: the compiler will determine the length of the array, and also the compiler will initialize the elements of the array based on the list you provide. No such thing as using a wrong index value or getting an ArrayIndexOutOfBoundsException.
It will be faster because the JVM (Java Virtual Machine) will not initialize the array with null values.
It will be faster because you don't have to specify explicit index values and the JVM does not have to work with them. Also the JVM does not have to check if indices are in the valid range (that is 0..length-1).
Less maintenance/overhead when later you want to add another element in the middle of the array, you just have to insert it where you want it. Would you have initialized your array the other way, you would have to update all subsequent indices.
The Java source code will be shorter, more compact and also the compiled byte code will be shorter.
You can read more about arrays in the Java Language Specification: Chapter 10. Arrays
The 'new' operator in java is responsible for the creation of new object or we can say instance of a class.
Actually, it dynamically allocates memory in the heap with the reference we define pointed from the stack.
Related
I want to know how to add or append a new element to the end of an array. Is any simple way to add the element at the end? I know how to use a StringBuffer but I don't know how to use it to add an element in an array. I prefer it without an ArrayList or list. I wonder if the StringBuffer will work on integers.
You can not add an element to an array, since arrays, in Java, are fixed-length. However, you could build a new array from the existing one using Arrays.copyOf(array, size) :
public static void main(String[] args) {
int[] array = new int[] {1, 2, 3};
System.out.println(Arrays.toString(array));
array = Arrays.copyOf(array, array.length + 1); //create new array from old array and allocate one more element
array[array.length - 1] = 4;
System.out.println(Arrays.toString(array));
}
I would still recommend to drop working with an array and use a List.
Arrays in Java have a fixed length that cannot be changed. So Java provides classes that allow you to maintain lists of variable length.
Generally, there is the List<T> interface, which represents a list of instances of the class T. The easiest and most widely used implementation is the ArrayList. Here is an example:
List<String> words = new ArrayList<String>();
words.add("Hello");
words.add("World");
words.add("!");
List.add() simply appends an element to the list and you can get the size of a list using List.size().
To clarify the terminology right: arrays are fixed length structures (and the length of an existing cannot be altered) the expression add at the end is meaningless (by itself).
What you can do is create a new array one element larger and fill in the new element in the last slot:
public static int[] append(int[] array, int value) {
int[] result = Arrays.copyOf(array, array.length + 1);
result[result.length - 1] = value;
return result;
}
This quickly gets inefficient, as each time append is called a new array is created and the old array contents is copied over.
One way to drastically reduce the overhead is to create a larger array and keep track of up to which index it is actually filled. Adding an element becomes as simple a filling the next index and incrementing the index. If the array fills up completely, a new array is created with more free space.
And guess what ArrayList does: exactly that. So when a dynamically sized array is needed, ArrayList is a good choice. Don't reinvent the wheel.
The OP says, for unknown reasons, "I prefer it without an arraylist or list."
If the type you are referring to is a primitive (you mention integers, but you don't say if you mean int or Integer), then you can use one of the NIO Buffer classes like java.nio.IntBuffer. These act a lot like StringBuffer does - they act as buffers for a list of the primitive type (buffers exist for all the primitives but not for Objects), and you can wrap a buffer around an array and/or extract an array from a buffer.
Note that the javadocs say, "The capacity of a buffer is never negative and never changes." It's still just a wrapper around an array, but one that's nicer to work with. The only way to effectively expand a buffer is to allocate() a larger one and use put() to dump the old buffer into the new one.
If it's not a primitive, you should probably just use List, or come up with a compelling reason why you can't or won't, and maybe somebody will help you work around it.
As many others pointed out if you are trying to add a new element at the end of list then something like, array[array.length-1]=x; should do. But this will replace the existing element.
For something like continuous addition to the array. You can keep track of the index and go on adding elements till you reach end and have the function that does the addition return you the next index, which in turn will tell you how many more elements can fit in the array.
Of course in both the cases the size of array will be predefined. Vector can be your other option since you do not want arraylist, which will allow you all the same features and functions and additionally will take care of incrementing the size.
Coming to the part where you want StringBuffer to array. I believe what you are looking for is the getChars(int srcBegin, int srcEnd,char[] dst,int dstBegin) method. Look into it that might solve your doubts. Again I would like to point out that after managing to get an array out of it, you can still only replace the last existing element(character in this case).
one-liner with streams
Stream.concat(Arrays.stream( array ), Stream.of( newElement )).toArray();
I currently am trying to understand how Java assigns space when I ask it to.
Specifically (and as I am aware that I'm unable to declare an array with generics) I made this assignment:
List<List<Visitor>> elevlists;
elevlists = new ArrayList<List<Visitor>>(5);
as I want elevlists to be a list of 5 lists of Visitors. To my understanding this command will clear out space for five lists of Visitors and not have them there.
So I added this, which (and I underline) doesn't work:
List<Visitor> (elevlists.get(0)) = new ArrayList<Visitor>();
to see if I can actually create an instance for any of the lists.
But after some tweaking I ended to this code:
List<List<Visitor>> elevlists;
elevlists = new ArrayList<List<Visitor>>(5);
List<Visitor> temp = (elevlists.get(0));
temp = new ArrayList<Visitor>();
which, to my surprise, seems okay to the compiler.
Any help on why this is acceptable when the code above it isn't?
Thanks a lot.
ArrayList is not a array. It's a wrapper for array.
List<List<Visitor>> elevlists;
elevlists = new ArrayList<List<Visitor>>(5);
Here you just create a object ArrayList with 5 elements. But all elements inside this array is NULL.
Proper code should be:
List<List<Visitor>> elevlists;
elevlists = new ArrayList<List<Visitor>>(5);
List<Visitor> temp = new ArrayList<Visitor>();
elevlists.add(temp);
This is not doing what you think it is.
List<Visitor> temp = (elevlists.get(0));
temp = new ArrayList<Visitor>();
The second line affects only the variable temp, which now points to a newly allocated ArrayList.
Read this as
get the value stored at element zero (which is currently null) in elevlists, assign that value to temp.
now throw away that value in temp, and instead make temp point to a new Array List
If you want to make elevlists have some non-null values use
elevlists.add(temp);
I think, although your second code will compile, it will fail at runtime because the elevlists = new ArrayList<List<Visitor>>(5); does not actually create elements in elevLists - the 5 is just a hint to the ArrayList class how much space to reserve. ArrayList is an array wrapper and doesn't reserve memory for an array in the same way as, say, C.
#Tom is right in comments - the first example doesn't compile because you can't have method calls on the LHS of assignments.
I've been reading up on it, but every question I've found has asked for slightly different things, such as only wanting a single letter for their array, or in a different language (I'm new and only learning java at the moment), so here I am.
I want to set up an array that uses the user's input for their names.
What I have so far is this, I'm assuming this is the declaration line, where later I use an input line to define a value within the array (which I also am unsure how to do)
String[] array = {"name"};
But I don't know how to for example print.out the object or keep up with which name will be what value. I appreciate your time taken to teach me!
EDIT for further clarification. I'm trying to write up a small app that asks the user for numerous names, addresses, and phone numbers (Type name -> Type name's address -> type name's phone number, ask if they want to add another person, if yes then go back to asking for another name)
I am unsure how to set up a String array or how to use it throughout. However, thanks to your input and coming back after some fresh air, I have a better idea how to word it for google. Thank you guys for your help, even if it was just to gesture a better articulated question.
An array is a sequence of values. You have created an array of Strings that is one String long. To access the value at a specific of an array, use array subscript notation: the name of the array followed by a pair of square brackets ([]) with the index in between them.
String[] anArrayOfStrings = {"string0", "string1", "string2"};
anArrayOfStrings[0]; //the first element
System.out.println(anArrayOfStrings[1]); //print the second element
anArrayOfStrings[2] = "new string value"; //assign the third element to a new value
if (anArrayOfStrings[0].equals("string0") //evaluate the first element and call a method
{
//this block will execute anArrayOfStrings[0] is "string0"
}
anArrayOfStrings[3]; //error, index out of bounds
Simply declaring the array would be
String[] names;
In your code you both declare and assign it in the same line by using an initializer list.
To assign individual elements, use the [] notation. Note that once you initialized you list to be only one String long, it cannot become longer than without be re-assigned. To declare an array of any size, you can use:
String[] arrayWithInitialSize = new String[5]; //holds five strings, each null to begin with
Suppose I have the following method signature
int f (int[] values)
and I call it like this:
int[] myValues = {1,2,3,4,5}
f (myvalues)
then, since arrays are objects, and objects are reference types, f receives a reference to the ints, and can change their value so the caller can see the changes.
Now how can I then call f in a way that it receives a reference to the array elements 2,3,4 (i.e. subrange from index 1 to 3 inclusive) without copying myValues?
Something like
f ((int[]) myvalues[1])
which of course does not compile (and would leave open which size the array would have) but might transport the idea I am looking for?
In other languages, I could use pointer arithmetics to calculate the address of myValues[2], and treat it a the beginning of an array of integer, and pass an explicit count parameter. (Quite type-unsafe, of course.)
Can I do this in Java without copying the three elements' values to an intermediate array?
Sub-question: Are the array elements, being value types, stored at consecutive addresses at all, or is the array composed of elements that are references to integers? Could it be the question does not make sense because even if the answer to the latter was "yes", I could not build on that since that would be an implementation detail that a Java source must not build upon it? It even cannot -- there is no semantics for it, right?
Edit: Stupid index error
You can use List instead of an array.
int[] myValues = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
List<Integer> myValuesList = Arrays.asList(myValues);
// change the argument of function to List
doSomething(List<Integer> input);
// and then just give the function a range of the myValues.
// This List is still backed by your array myValues, it just
// a view of the original array.
doSomething(myValuesList.subList(2,3));
You cannot return a range/subset of items in arrays (also Collection) without creating a new instance of the container.
I cannot answer the second without guessing, but IF the JVM wants to allocate 2 regions of memory for one array, it can do it without you knowing.
In C/C++ this would be terribly easy to do with a bit of pointer arithmetic, but in Java, I am not so sure it is possible.
The best you could do is use the copyOfRange method although that makes a deep copy.
I am having an Array of String of 10 elements.
Now I need to compare my value available in any of these Arrays value.
1 Option I thought of sorting the array and then binary search on the
same
But further analysis, I found the value needed to be compare is not exactly same, it contains some value , but even in that case, it should be successful.
Like Value to compare ,
String str = "Author"
String[] arrays = {"#Author","#Auth",#Au...}
str.contains(arrays..) actually but how to do the same .
you could use Dynamic Programming:
http://www.algorithmist.com/index.php/Longest_Common_Subsequence
this algorithm check the longest subsequence of string with the minimum complex
This is the algor in java:
http://introcs.cs.princeton.edu/java/96optimization/LCS.java.html
If you are only dealing with an array with only 10 elements... you don't need to worry about efficiency!
You can simply loop through the entire array, or instead of using a String[] use an List<string> and use the contains method.