In a method I created I am trying to create is meant to return an array of user inputted strings. The issue that I am having it the compiler is saying that userData may not be initialized at userData[i]=tempData; and at return userData;. I am unsure why this error is occuring, and would like some feedback.
public String[] getStringObj() {
int i = 0;
String tempData;
String[] userData;
Boolean exitLoop = false;
System.out.println("Please list your values below, separating each item using the return key. To exit the input process please type in ! as your item.");
do {
tempData = IO.readString();
if (tempData.equals("!")) {
exitLoop=true;
} else {
userData[i] = tempData;
i++;
}
} while (exitLoop == false);
return userData;
}
In the interests of improving code quality:
You don't need that exitLoop flag; just do
while(true) {
String input = IO.readString();
if(input.equals("!")) {
break;
}
/* rest of code */
}
Since you seem like you want to just add stuff to an array without bounds, use an ArrayList instead of an array (added bonus, this gets rid of i too):
List<String> userData = new ArrayList<String>();
...
userData.add(line);
If you do these two things, your code will be much more concise and easy to follow.
Your userData is not initilaized and you are attempting to use it here userData[i]=tempData; before initialization.
Initialize it as
String[] userData = new String[20];
//20 is the size of array that I specified, you can specify yours
Also in your while condition you can have while(!exitLoop) instead of while(exitLoop==false)
You didn't initialize the String[]. Just do String[] userData = new String[length]. If you are unsure of the length, you may just want to use an ArrayList<String>.
Related
I am a true beginner to programming, so forgive me.
I have a String Array filled with a set of quotes that I have a method randomly picking one to display on the screen. This all works perfectly, I'd like to take the next step now. I would like to have the ability to add text to this array that a user inputs on an Activity that I have created. I understand that Arrays are Immutable, but I am failing to figure out how to create an ArrayList, pre-fill it with my 50ish quotes and then have the ability to add more through the app later.
Here is the code I currently have...
public class FactBook {
public String[] mFacts = {
"Quote 1.",
"Quote 2.", };
public String getFact() {
String fact = "";
Random randomGenerator = new Random();
int randomNumber = randomGenerator.nextInt(mFacts.length);
fact = mFacts[randomNumber];
return fact;
}
References
ArrayList
Arrays
import java.util.ArrayList;
import java.util.Arrays;
public class FactBook {
// Public data members are not recommended.
// Make it at least protected and arrange controlled access to it
// by specific methods
public ArrayList<String> mFacts =
new ArrayList<String>(
Arrays.asList("Quote 1.", "Quote 2.")
)
};
public String getFact() {
String fact = "";
// Do you need to create a new Random every time?
// Perhaps creating it only once and storing it in a static
// (class wide) data member will be just as good: create it once,
// reuse it later.
Random randomGenerator = new Random();
int randomNumber = randomGenerator.nextInt(mFacts.size());
fact = mFacts.get(randomNumber);
return fact;
}
// how to add
public void add(String newQuip) {
// Don't accept null or "all-white character" quotes
if(null!=newQuip && newQuip.trim().length()>0) {
this.mFacts.add(newQuip);
}
}
}
Look at Arrays class.
It has a helper method exactly for those cases:
List<String> facts = Arrays.asList("string1", "string2", ...);
Here's a simple method that pre-populates an ArrayList with your values, and then allows you to add more values to it later on
private ArrayList<String> createPrePopulatedList() {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("Quote 1.");
///Add any more you want to prepopulate like this
return arrayList;
}
You can call this method like so.
private ArrayList<String> myArrayList = createPrepopulatedList();
Now you can simply add whatever you want to it dynamically with add().
You should probably do some reading on Java data structures before you jump into Android programming. Here's some help with ArrayList https://www.tutorialspoint.com/java/java_arraylist_class.htm
EDIT :
ok, sorry for not so clear question. Let's try other way:
We have an ArayList of names : Peter, John, Adam
We are looking for String name;
If ArrayList contains the String, we want to write the String. If ArrayList doesn't contains the String, we want to add the String into the ArrayList.
If I'm looking for "Adam", then this program is not working, because first it finds name "Peter", then "John", and only after that it finds "Adam". So for the first 2 times, it thinks, "Adam" is not in the list, and acts so.
String findName;
for (i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i).getValue().contains(findName)) {
System.out.println(findName);
break;
}
else
arrayList.add(findString);
}
Original question :
I have a String and an Array (ArrayList). I have to do something, if the String is in the Array and something else, if it is not in the Array. How do I do that?
I can't do it like this :
String myString;
for (i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i).getValue().equals(myString)) {
DO SOMETHING;
break;
}
else
DO SOMETHING ELSE;
}
because it will find the String only once and all the other times it will act, like the arraylist doesn't contains the String.
So I'm doing it like this :
String findString = "0";
String myString;
for (i = 0; i < arrayList.size(); i++) {
if (arrayList.get(i).getValue().equals(myString)) {
DO SOMETHING;
findString = "2"; //when I find the String, I change this
break;
}
if findString == "0"; //if I have not found the String, this happens
DO SOMETHING ELSE;
}
and I have the feeling, it should be not done like this. ;)
I know I can use booleans instead of this way, but it's the same in other way. Isn't there total different way of doing this correctly?
Cleanest way is as follows: Declare a method which returns whether the string is in the array:
public boolean arrContainsStr(String str, String[] arr) {
for (int i = 0; i < arr.length; i++) {
if (arr[i].equals(str)) {
return true;
}
}
return false;
}
Then use this method in your code like this:
String myString;
String[] myArray;
if (arrContainsStr(myString, myArray)) {
DO SOMETHING;
}else {
DO SOMETHING ELSE;
}
This is for primitive string arrays. Note that if you are using an ArrayList or similar, you can simply use the .contains(myString) method to check if the list contains your string. Documentation here: https://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#contains(java.lang.Object)
This question is a bit odd, but just reading your first sentence, if you want to see if a List e.g. ArrayList contains an object (e.g. a String) you can just use the contains(Object o) method rather than looping through. I must be missing your point. In any case, an example:
String stringToFind = "Foo";
List<String> stringList = new ArrayList<>();
stringList.add("Foo");
if (stringList.contains(stringToFind)) {
System.out.println("String found");
} else {
System.out.println("String not found");
}
Output: String found. (In this example).
Couldn't you use .contains as below to check if the String is in the list?
if(arrayList.contains(myString)){
// DO SOMETHING
} else {
// DO SOMETHING ELSE
}
You could set a boolean to true if you find your value then break.
If you don't find the value, the boolean will stay to false.
Then you do the if
Its a little vague so I'm not sure if this is what you want, but if you remove the break in the first segment of code i think you will get what you want. do you want it do DO SOMETHING for every occurrence of the string or just the first one. also if you do need the break you could check the value of i after the loop terminates so
if(i==arrayList.size())
{
//String found
}
else
{
//String not found
}
Ok, not sure if the title worded that correctly but say I have three objects with two strings of data each(Lets say a stateName and a cityName) stored into an arraylist. Is it possible to enter in a state name in as a string variable(call it searchStateName), then have a method search through the objects in the list and compare searchStateName to the stateName inside each object in the arraylist, and when a match is found have it return the cityName that is inside the same object as the matching stateName?
I am trying to do something similar currently and would like to figure it out myself, but I have been working on this for the past hour and am completely lost. Could anyone point me in the right direction?
This is the approach. Say you have a class called SC and you have two instance variables in it and getters and setters for them. You need to initialize 3 objects of them inside your main:
SC a = new SC("Illinois ","Chicago ");
SC b = new SC("Michigan ","Detroit");
SC c = new SC("New York"," New York");
And then create an ArrayList of object SC and add those 3 objects of SC to that ArrayList.
ArrayList<SC> list = new ArrayList<SC>();
list.add(a);
list.add(b);
list.add(c);
Now call the method that search for a state name and returns the city name if it finds it:
this.searchStateName("Illinois");
The actual implementation of this method with for-each loop:
public String searchStateName(String stateName){
String result = "No city found.";
for (SC sc : list )
if (sc.getStateName().equalsIgnoreCase(stateName)){
result = sc.getCityName();
break;
}
}
return result;
}
If you are not comfortable with for-each loop then you can use the regular for loop below. I commented out on purpose. But it will work correctly and give you the correct city name.
//public String searchStateName(String stateName){
// String result = null;
// for (int i = 0; i < list.size(); i++){
// if (list.get(i).getStateName() .equalsIgnoreCase(stateName)){
// result = list.get(i).getCityName();
// break;
// }
// }
// return result;
//}
And thats it. Let me know if you need help further.
Is it possible in Java to redefine value after it already been defined(Like in JavaScript)? Take a look at my sample code, I am trying to redefine String array.
public String[] checkIfLengEnglish (){
String language = Locale.getDefault().getDisplayLanguage() ;
String LG = Locale.getDefault().getLanguage();
if(LG.contains("en")){
String language[] = {"English"}; // Redefining
}
else {
String Language[] = {"English/"+ Language,Language,"English"}; // Redefining
}
return Language[];
}
you re-define Language in your code with multiple types at multiple scopes (once at the method level, twice in the if-block/else-block). Don't do that.
You don't need to add the [] to reference an array variable, don't do that.
Since you declare the array inside the if-block, it only exists inside the if-block. To fix this, you need to declare it outside:
String[] languages;
if( LG.contains("en")){
languages = new String[] {"English"};
}else {
languages = new String[] {"English/"+ Language,Language,"English"};
}
return languages;
Since you no longer use initalization (which can only happen when you declare a variable) but assignment, you need to use the "long form" for specifying the array values, which includes new String[].
Also note that as a general guideline, method and variable names should start with a lower-case letter and class/interface/enum names should start with a capital letter. That's not technically required, but following this guideline will make your code easier to understand for others.
just reframing your code & variables for better understanding purpose
public String[] CheckIfLengEnglish (){
String displayLanguage = Locale.getDefault().getDisplayLanguage() ;
String LG = Locale.getDefault().getLanguage();
String arrayLanguages[];
if( LG.contains("en")){
arrayLanguages = {"English"};
}else {
arrayLanguages = {"English/"+ Language,Language,"English"};
}
return arrayLanguages ;
}
Language[] is defined inside your if/else statement. You should try putting it above that like
String[] array = new String[];
if(true){
array = {"English"};
}
return array;
// dummy example
String[] Language=new String[];
if
{
Language={"English"}
}
else {
String Language[] = {"English/"+ Language,Language,"English"};
}
return Language[] ;
I'm new to the idea of using an ellipsis. I'm almost certain my error is caused by improperly declaring or initializing "String[] authors", but I don't know how to do this an still have my setAuthors method work.
import java.util.*;
public class Book {
private String[] authors; //I'm guessing this line should end with "= new String..."
//but not sure how to w/o specifying an array dimension
private int authorsSize;
//Receives variable # of String parameters and indices them into String[] "authors"
public void setAuthors(String... authors) {
authorsSize = authors.length;
for(int i=0;i<authorsSize;i++)
this.authors[i] = authors[i];
}
//getAuthors method:
public String getAuthors(){
String s = "";
authorsSize = authors.length;
for(int i=0;i<authorsSize;i++)
s = s+authors[i] + ", ";
printAuthors = s;
return s;
}
The simplest approach would just be to clone the array:
public void setAuthors(String... authors){
this.authors = (String[]) authors.clone();
}
After all, you're overwriting the previous data anyway, and you can't know the size before the method call. You don't need the authorsSize variable at this point - you've got the authors array which knows its own length.
(If you were able to use immutable collections, you wouldn't even need to bother cloning, of course.)
EDIT: As noted in comments, this method will throw an exception if you pass in a null reference. You shouldn't automatically decide that this is a situation you should "handle" - it's entirely legitimate to document that the parameter must not be null. I would suggest documenting the behaviour around nullity either way.
Indeed, if you do this you might also want to initialize your instance field like this:
private String[] authors = new String[0];
That way you always know you'll have a non-null reference in that field, so you can use it with impunity. I would prefer this over having to check for null on every use.
you never initialized authors your array .
you need to initialize it before you use it .
String[] authors = new String[size];
//but not sure how to w/o specifying an array dimension
The best way is to use an List implementing classes as they are dynamic Arrays. i.e., you dont need to specify the size.
List<String> authors = new ArrayList<String>();
You have to currect your setAuthors method as described below
public void setAuthors(String... authors) {
if (authors != null && authors.length > 0) {
authorsSize = authors.length;
authors = new String[authorsSize];
for (int i = 0; i < authorsSize; i++)
this.authors[i] = authors[i];
}else{
this.authors = null;
}
}
Because the declaration of "private String[] authors" is before that of "public void setAuthors(String... authors)", you can not use the format like "String[] authors = new String[authorsSize]". This will make the size of authors always be 0.
The better way is to use the dynamic initialization:
List authors = new ArrayList();
Then use this.authors.add(authors[i]) to pass parameters.
you could also adjust your code like so:
import java.util.*;
public class Book{
private String[] authors;
private int authorsSize;
public void setAuthors(String... authors){
//check for null, you could also set this.authors = new String[] if you prefer.
if(authors == null){
this.authors = null;
}else{
authorsSize = authors.length;
//also add this line...
this.authors = new String[authorsSize];
for(int i=0;i<authorsSize;i++)
this.authors[i] = authors[i];
}
}
public String getAuthors(){
if(authors == null){
return ""; //could also return null here if you would prefer
}
StringBuilder s = new StringBuilder();
authorsSize = authors.length;
for(int i=0;i<authorsSize;i++){
if(i > 0)
s.append(",");
s.append(authors[i]);
}
//printAuthors = s;
return s.toString();
}
}