Array list code in java not working - java

Hello guys I am trying to write an array list of strings with not specified size, I am setting a for loop with a sentinel to control the amount of input, but it seems not to work, this is the piece of cod that has the problem I think, Pleasse help !
public static void main(String args[])
{
ArrayList<String> a=new ArrayList<String>();
String string;
String string2;
char[] string1=new char[1];
char c;
for(int i=0;!"null".equals(a.get(i));i++)
{
string=input.nextLine();
a.add(i,string);
}

I assume you are getting an error. I suggest you read the error and if you don't understand it, you should search for it or include it in the question.
In this case, your test is broken. You don't have either a null value or "null" (which is not the same thing) in fact you don't have an element 0 which is why it is throwing an exception.
A simple solution is to check what you reading as you read it.
List<String> a = new ArrayList<String>();
while(input.hasNext())
a.add(input.readLine());

!"null".equals(a.get(i)) will just check if the string returned by a.get(i) does not equal "null". I think what you wanna do is check a.get(i) == null, which will not work since requesting an item from a List that is at an index that is bigger than the list's size will throw a java.lang.IndexOutOfBoundsException.
To properly iterate over a List, use a foreach loop:
for(Object o : list) {
//Execute your code
}

I think the part where I have to get a false value by !"null".equals(a.get(i)) is not working like it should because the program does not get out of the loop

Related

ArrayList as Archive

My task is:
The program should read items from the user. When all the items from the user have been read, the program prints the information of each item.
For each item, its identifier and name should be read. If the identifier or name is empty, the program stops asking for input, and prints all the item information. Modify the program so that after entering the items, each item is printed at most once. Two items should be considered the same if their identifiers are the same (there can be variation in their names in different countries, for instance).
If the user enters the same item multiple times, the print uses the item that was added first.
I have done the code below, but it will still add items with the same identifier.
Why? How can I fix it?
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
ArrayList<String> itemsName = new ArrayList();
ArrayList<String> itemsIdentifier = new ArrayList();
while(true){
System.out.println("Identifier? (emppty will stop)");
String identifier = scanner.nextLine();
if( identifier.isEmpty()){
break;
}
System.out.println("Name? (emppty will stop");
String name = scanner.nextLine();
if(name.isEmpty()){
break;
}
if(!(itemsIdentifier.contains(identifier))){
itemsIdentifier.add(identifier);
}
if(!(itemsName.contains(name))){
itemsName.add(name);
}
}
System.out.println("==Items==");
int j = 0;
for(String i: itemsIdentifier){
System.out.println(i + ": "+ itemsName.get(j));
j++;
}
}
}
I think the problem with your code is that you are adding name into itemsName list even when you are not adding identifier into itemsIdentifier list in the following lines
if(!(itemsIdentifier.contains(identifier))){
itemsIdentifier.add(identifier);
}
if(!(itemsName.contains(name))){
itemsName.add(name);
}
Ideally shouldn't you either add both name and identifier or don't add any?
You have a while(true) loop which will keep going indefinitely, you are breaking the loop only if the user input is empty, but you are not doing anything when the lists already contain an identifier more than once. (You are adding to the list if you have a unique identifier).
EDIT
I have other misgivings on the code above (I am assuming that this is an assignment), but since I do not know if you built this on top of what the lecturer gave you, I can only speculate. Some thoughts on the code above:
You could create your own Record object.
As per the instructions, you would need to override the equals method.
Instead of having two lists, you would have only 1 list of type Record.
Try something like this:
if(!(itemsIdentifier.contains(identifier))) {
itemsIdentifier.add(identifier);
itemsName.add(name);
}
In your code, if the id is already in the list, the name could still be added...
You only need to check whether the identifier is similar or not. The name similarity condition is not required. As long as the identifiers are different( though they have the same name), you still add them to the itemsIdentifier and itemsName. On the other hand, if the identifiers are identical, there is no need to run a check on the similarity of the name.

what is the difference between executing For loop Java

Could you tell me, what is the difference between For Loop Java in Code A and B? while both of them gives a same result in executing? and i know what they are doing, but why is For loop written this way in the code *A*
Thanks
The code
//Code A
public class MyArray {
public static void main (String[] args){
int[] a ={1,10,30,40,50};
for (int i : a)
{
System.out.println(i);
}
}
}
//====================================
//Code B
public class MyArray{
public static void main (String[] args){
int[] a ={1,10,30,40,50};
for (int i=0;i< a.length; i++)
{
System.out.println(a[i]);
}
}
}
Iterating over a collection is uglier than it needs to be. Consider the following method, which takes a collection of timer tasks and cancels them:
void cancelAll(Collection<TimerTask> c) {
for (Iterator<TimerTask> i = c.iterator(); i.hasNext(); )
i.next().cancel();
}
The iterator is just clutter. Furthermore, it is an opportunity for error. The iterator variable occurs three times in each loop: that is two chances to get it wrong. The for-each construct gets rid of the clutter and the opportunity for error. Here is how the example looks with the for-each construct:
void cancelAll(Collection<TimerTask> c) {
for (TimerTask t : c)
t.cancel();
}
for each is just a better way of iterating.
Limitation:
in for-each loop you will not be able to know which number of element(index of the element in collection) you are processing, you need to define counter for the same, while in simple for loop i tells you the number of the element you are processing.
Code A by is just syntactic sugar for code B and works on Java versions 5 or later.
The advantage is that you do not have to handle the mundane indexing code on your own.
Code A is also known as the foreach loop
Plus Code A also works if instead of int[] you had a Collection, thus giving you a uniform way of iterating over arrays and collections (or to be ever more precise, any subclass of Iterable)
Practically, no difference, but code A is easier to read and harder to make a mistake.
The shorter version of the for loop means for each index in the array, which quite simply is easier to understand.
The other for loop is a most commonly used which starts from a assigned starting value and goes on till the end of array.
The selection depends on the situation according to me. There might be a time when using the codeA format would give a better understanding to the one who debugging the application.
The answers here have not pointed to a certain vital difference: in code A, you cannot simply change the elements of the array, because the i is just a reference, while in code B, you can do a[i] = //something.
If your array was an array of some Objects and you just wanted to use Mutability, then there is no difference.
Actually both codes are equal as first code if in the right-hand side of the for(:) array rather than an Iterable object (as in this case), the internal code uses an int index counter and checks against array.length. which is equivalent to:
for (int i=0;i< a.length; i++)
{
System.out.println(a[i]);
}
Advantage of first code is its internally handle the end condition and short in writing then the second one.
but if object is iterable then it converts to:
for(Iterator<String> i = iteratableObject.iterator(); i.hasNext(); ) {
String item = i.next();
System.out.println(item);
}

How to return an array in java? Using Eclipse

Heres what I have for the method:
public int[] generateNumbers(int numberOfTimes){
int[] generatedNumbers = new int[numberOfTimes];
int counter = 0;
while(counter < generatedNumbers.length){
generatedNumbers[counter] = generator.nextInt(this.maxNumber - this.minNumber + 1) + this.minNumber;
counter++;
}
return generatedNumbers;
}
I created a JUnit4 Test, and just to test its output, I have this:
#Test
public void testGenerateNumbers() {
assertEquals(this.simulator.generateNumbers(1), 2);
}
Now, this returns false obviously, and the expected value was <[I#6f1d0b1>. Why am I getting a location instead of the actual array? Any help would be appreciated... By the way, we must use assertEquals, so anything else is out of the question, and yes I realize using something else to test this is easier.
You need to use assertArrayEquals()
assertArrayEquals(this.simulator.generateNumbers(1), new int[] {2});
Why am I getting a location instead of the actual array?
You're getting the array (reference), but the error message is printing out the result of calling toString() on it. That's not terrible useful to you, unfortunately.
If you're actually trying to check the length, you need to do that:
assertEquals(1, simulator.generateNumbers(1).length);
Or to check the first value within the array:
assertEquals(2, simulator.generateNumbers(1)[0]);
(Note that the expected value comes first. It's really important to get the "expected" and "actual" order right in order to make the error messages sensible.)
Of course assertArrayEquals is the best approach here, but if you really need to use assertEquals, you could convert the array to a list:
assertEquals(Arrays.asList(new int[] { 2 }),
Arrays.asList(simulator.generateNumbers(1)));
(It's not clear why assertEquals would be the only kind of assertion available to you... that's a very odd constraint.)
If you absolutely must use assertEquals (I'd like to know why), you can do this:
assertEquals(true, Arrays.equals(new int[] { 2 }, this.simulator.generateNumbers(1)));

return a sorted array but check if its empty or not

A newbie in java.
I am trying to implement some of the basic algorithms in java.
But I am unable to think about this fundamental case..
public int[] sort(int[] input){
if (input.length == 0 ) // return error?? but how
if (input.length == 1) return input
//sorting algo
}
whats a good way to throw error for empty array?
It should not be the responsibility of the sort function to return an error given an empty array, it should just return an empty array. A well behaved generic function shouldn't throw an error for what in normal circumstances is a perfectly valid input.
If an empty array is an error for some other semantic reason, that should be detected by the caller of the function beforehand.
If in your particular application you want to avoid the repetition of performing a zero-length check before each sort call, write a wrapper function that explicitly calls out the zero length behaviour and then invoke that instead, e.g.:
public int[] sortNonEmptyArray(int[] input) {
if (input.length == 0) {
throw new IllegalArgumentException("empty array passed");
}
return sort(input);
}
You can either return an IllegalArgumentException with a message saying that empty array is not allowed as the argument, or you can define your own custom error class. The first one is preferable as it's more simple.
However, you can run into trouble if you use some sort of divide-and-conquer sorting algorithm, and in one step of recursion you pass in an empty array to this method, which is considered sorted (sorted array with zero elements, yes, that can happen). In that case, you should simply return your empty array as return value (it will also form one of your base conditions in recursion).
public int[] sort(int[] input) {
if (input==null||input.length == 0) {
throw new IllegalArgumentException("empty array");
}
//sorting algo
return input;
}
I would follow the convention set in java.util.Arrays#sort and return the empty array.
Java Doc

What would be a safe way to split a string into multiple parts in Java?

Let me clarify the question I am asking. I have a java program I am working on that takes input from the keyboard via a readline library called JLine2. The library takes the entire line types as a command instead on breaking it up into space separated commands and arguments. What I am looking for is a safe way to break up the string that is passed as input.
I have tried using an array but since I am in the early stages of concept I don't yet know how many arguments my largest command will have so using a pre-initialized array I don't think will work. The problem I have ran into is when I check for null values in the array or when I check to see if a particular command or argument is present. Java keeps throwing an exception about the array index being out of scope or something. Because the array does not actually have a value for say array index 1 which is an argument to command in array index 0.
So what I am looking for is a way to take a string and safely split it into parts without having Java yelling at me when and array exception has occurred.
Here is the very slim code I can provide...
ConfigShell.class
package shell;
import java.io.IOException;
import configFS.ConfigFS;
import jline.console.ConsoleReader;
public class ConfigShell {
private ConfigFS config;
public ConfigShell() throws IOException {
config = new ConfigFS();
}
public void init() throws IOException {
ConsoleReader console = new ConsoleReader();
// When the program starts we want to be placed at / (root).
console.setPrompt(">> ");
// In this case an infinite loop is better than a loop based on whether line is equal to null.
// This allows line to be equal to null and still stay inside the shell.
while (true) {
String line = console.readLine();
if (line != null) {
// If pre-initialize the array I can check for null as a value for an array index.
// If I did this at time I needed the array and there were not enough index occupied the system would return an exception.
String[] cmdArgs = new String[4];
// We need to split up the incoming line because JLine2 does not do it for me.
// This allows me to evaluate the entire command piece by piece rather all at once.
cmdArgs = line.split("\\s+");
if (cmdArgs[0] != null && cmdArgs[0].equals("add")) {
if (cmdArgs[1] != null && cmdArgs[1].equals("server")) {
if (cmdArgs[2] != null) {
config.addServer(cmdArgs[2]);
System.out.println("Added server " + cmdArgs[2] + " to the configuration successfully.");
}
}
}
if (cmdArgs[0].equals("exit")) {
System.exit(0);
}
}
}
}
}
Note for testing: My Start.class main method makes a call to the init method in the above file.
You can do:
String cmdArgs = line.split("\\s+");
and then, before accessing any particular index, check the size of the array so that you do not get ArrayIndexOutOfBoundException
Something like this:
if(cmdArgs.length>=2){
//It means you have at least 2 elements
//Now its safe to access cmdArgs[0] and cmdArgs[1]
}
If all your problem is to have a storage for a variable number of strings you can use ArrayList<String> object.
You declare it like ArrayList<String> as = new ArrayList<String>();
Then when you split something from your command string you will simply use add method:
as.add(yourString);
If you need to retrieve a particular element of the ArrayList you can use its get method:
as.get(0);
You can process all elements with for each loop:
for(String str: as) {
println(str):
}
Have a look here for info and here for an example.
As I think you can use StringTokenizer class and its methods for your requirement.
see the sample code below:
if(line!=null)
{
StringTokenizer st=new StringTokenizer(line);// by default it takes space as delimiter....you can use as required as second argument in constructor...
while(st.hasMoreTokens())
{
String token1=st.nextToken();
// do your stuffs here..........
// I don't know exactly about your required logic here......
/* if(token1.equals("add"))
{
String token2=st.nextToken();
if(token2.equals("server"))
{
String token3=st.nextToken();
config.addServer(token3);
System.out.println("Added server " + token3 + " to the configuration successfully.");
}
}
*/
}// while closing...
}// outer if closing...
Or as PM 77-1 told you can use ArrayList. But as my opinion LinkedList should be a better option here.

Categories

Resources