My program calls for being able to delete a name and number from a phone book. I have gotten the deleting to work but it only deletes the index from the ArrayList that the text box corresponds to. I need to be able to delete both the name and the number from their respective arraylists by entering it into either texbox. Sorry if there is another answer to this i guess i dont really know how to word it correctly. My code is below.
ArrayList<String> Names = new ArrayList<String>();
ArrayList<String> Numbers = new ArrayList<String>();
if(e.getSource() == DeleteBtn)
{
if (NameTxt.getText() != null)
{
for( int i=0; i<= NamesList.size(); i++)
{
if(NamesList.contains(NameTxt.getText()))
{
NamesList.remove(i);
System.out.println(NamesList.size());
}
}
}
if (PhoneTxt.getText() != null)
{
for( int i=0; i<= NumbersList.size(); i++)
{
if(NumbersList.contains(PhoneTxt.getText()))
{
NumbersList.remove(i);
System.out.println(NumbersList.size());
}
}
}
}
If you HAVE to use ArrayLists then you might consider using an ArrayList of pairs.
You can create your own class, say PhoneBookEntry.
class PhoneBookEntry {
String _name;
String _phone;
// etc...
}
ArrayList<PhoneBookEntry>
Consider using a HashMap instead of the ArrayLists.
HashMap<String, String> numbersAndNames = new HashMap<String, String>();
numbersAndNames.put("John", "123 456 789");
If I were you, I would reconsider my logic. I'm going to try and avoid posting code for you to keep from giving you the answer/doing the work for you but...
I only see you modifying the NamesList variable. You aren't modifying the Names or Numbers ArrayList variables.
I would put your 'contains if statement' some place else. Your checking to see if NameList contains NameText a bunch of times. I don't see why you would need to check it more than once.
If you want to get smart, you can do away with the array completely and just use the getIndex() method to some effect in java...which gets the index corresponding to NameText (I'm being vague here deliberately, so think about what I'm saying).
You can use a HashMap if you want, but it's not necessary.
Per suggestion of using an additional class to track the name/number combo.
ArrayList contacts = new ArrayList();
if(e.getSource() == DeleteBtn) {
if (NameTxt.getText() != null) {
for( int i=0; i<= contacts.size(); i++) {
if(contacts.getName().contains(NameTxt.getText())) {
contacts.remove(i);
System.out.println(contacts.size());
}
}
}
public class PhoneContact {
private String name;
private String number;
/*
Getters and Setters
*/
}
First of all, NumbersList.contains(PhoneTxt.getText()) returns if PhoneTxt.getText() is anywhere in the list.
What you want to check is the NumbersList.get(i).equals(PhoneTxt.getText()) note that i used equals() instead of == operator
my friend actually found the answer, he simply added the other ArrayList(i), thank you to all who posted answers, as they gave me food for thought, just thought the logic of the answer would not work but i was proven wrong, here is the code for anyone interested.
if(e.getSource() == DeleteBtn)
{
if (NameTxt.getText() != null)
{
for( int i=0; i<= NamesList.size(); i++)
{
if(NamesList.contains(NameTxt.getText()))
{
NamesList.remove(i);
NamesList.remove(i);
System.out.println(NamesList.size());
System.out.println(NumbersList.size());
}
}
}
if (PhoneTxt.getText() != null)
{
for( int i=0; i<= NumbersList.size(); i++)
{
if(NumbersList.contains(PhoneTxt.getText()))
{
NumbersList.remove(i);
NamesList.remove(i);
System.out.println(NamesList.size());
System.out.println(NumbersList.size());
}
}
}
}
Related
private ArrayList<Suspect> accomplices = new ArrayList<Suspect>();
public void checkAndAddAccomplice(Suspect aSuspect) {
for(int i=0; i<aSuspect.getAccomplices().size(); i++) {
if(!(aSuspect.getName().equals(aSuspect.getAccomplices().get(i).toString()))) {
accomplices.add(aSuspect);
}
}
}
This is the code and i dont know why but the array stays empty even after this method.
This is starting to become really frustrating.
you should be comparing aSuspect.getName() with aSuspect.getAccomplices().get(i).getName(), instead of aSuspect.getAccomplices().get(i).toString()
if(!(aSuspect.getName().equals(aSuspect.getAccomplices().get(i).getName()))) {
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
}
My method applyBonus() from the class BonusEmporium gets bonus objects from the arrayList of City objects and applies them to a Player object.
when i write my function like this i have no problem testing it:
public class BonusEmporium extends Bonus {
public BonusEmporium(int cities) {
this.setBonusType(BonusType.EMPORIUM);
this.cities=cities;
setCity(new ArrayList<City>(cities));
}
public void applyBonus(Player player){
Bonus bonus=getCity().get(0).getBonus().get(0);//gets the first bonus from the first
//city
bonus.applyBonus(player);
Bonus bonus=getCity().get(0).getBonus().get(1);//gets the second bonus from the first
//city
bonus.applyBonus(player);
Bonus bonus=getCity().get(1).getBonus().get(0);//gets the first bonus from the
//second city
bonus.applyBonus(player);
}
}
The problem is when i want to run it only while the arraylists contain elements, how do i check that an element from an array is empty?
public class BonusEmporium extends Bonus {
public BonusEmporium(int cities) {
this.setBonusType(BonusType.EMPORIUM);
this.cities=cities;
setCity(new ArrayList<City>(cities));
}
public void applyBonus(Player player){
int i=0,j=0;
while(j<cities){
while(getCity().get(j).getBonus().get(i)!=null){//In theory this should
//verify that the element bonus i from the city j is not empty
//but i get NullPointerException
Bonus bonus=getCity().get(j).getBonus().get(i);
bonus.applyBonus(player);
i++;
}
j++;
}
}
}
It's difficult to tell what you are asking, but you should be able to avoid the error by handling the message chain better.
public void applyBonus(Player player){
List<City> cities = getCity();
for(int i = 0; cities != null && i < cities.size(); i++){
City c = cities.get(i);
List<Bonus> bonuses = c.getBonus();
for (int j = 0; bonuses != null && j < bonuses.size(); j++) {
Bonus b = bonuses.get(j);
if (b != null)
b.applyBonus(player);
}
}
}
You check if the element is empty like this:
if(array != null && array.get(index) == null) // element is null when empty
To check if the array as a whole is empty (has no elements):
if(array != null && array.isEmpty())
In general the problem in java is chaining getters like this:
getCity().get(j).getBonus().get(i)!=null
You can get nullpointer exception from 4 places here. You can check them all like:
if (getCity()!=null &&
getCity().get(j) &&
getCity().get(j).getBonus() &&
getCity().get(j).getBonus().get(i)!=null){
....
}
Other way could be encapsulating whole code in try - catch and catching NPE, which is more like hack.
I also suggest using foreach instead while and don't store array size in separate variables, because you can always get it using
myArr.getSize()
And also check javadoc about ArrayList constructor:
new ArrayList<City>(cities)
because this is likely not doing what you expect
Short story:
init all ArrayLists in constructor (don't specify size)
use foreach loops
don't put nulls into the arrays
and you should be fine without checking for empty elements
In my Java program's constructor I have the following:
thirdRow.add(button);
button.setActionCommand("Sumbit");
button.addActionListener(this);
And here is the corresponding actionPerformed method that's supposed to take 3 values from some textfields and store them into arrays:
public void actionPerformed(ActionEvent e)
{
String arg = e.getActionCommand();
if (arg == "Submit")
{
//enlarge arrays
qtyStr = enlargeArray(qtyStr);
typeStr = enlargeArray(typeStr);
colorStr = enlargeArray(colorStr);
//add from textfields into current
qtyStr[qtyStr.length-1] = qty.getText();
typeStr[typeStr.length-1] = type.getText();
colorStr[colorStr.length-1] = color.getText();
}
}
//method to enlarge an array by 1
public String[] enlargeArray(String[] currentArray)
{
String[] newArray = new String[currentArray.length + 1];
for (int i = 0; i<currentArray.length; i++)
newArray[i] = currentArray[i];
return newArray;
}
When I run the application, populate the textfields, and click the submit button nothing happens. How can I verify that my string arrays are being appended like they're supposed to?
You've a problem here: if (arg == "Submit")
Don't compare Strings using ==. Use the equals(...) or the equalsIgnoreCase(...) method instead. Understand that == checks if the two objects are the same which is not what you're interested in. The methods on the other hand check if the two Strings have the same characters in the same order, and that's what matters here. So instead of
if (fu == "bar") {
// do something
}
do,
if ("bar".equals(fu)) {
// do something
}
or,
if ("bar".equalsIgnoreCase(fu)) {
// do something
}
Also, for safety's sake, I try to use String constants wherever possible so as not to be tripped up by misspellings.
If you want to do your code this way, I would probably do two things:
1) maintain index fields for each array for the next free index, and
2) I wouldn't recommend resizing your array by 1 each time, as our current code is running through the array 2 n times (n = array length), 1st to initialize the array, and 2nd to create a new array.
Two options to optimize thisL one would be be to look into the Arrays class. it contains methods such as Array.copyOf() that can perhaps be useful here. You could also check if the array is full, and if it is then resize it by a number greater than one to reduce extra work.
For instance:
import java.util.Arrays;
class Test{
private String[] a;
private int next;
public Test(int size){
a = new String[size];
next = 0;
}
public void add(String s){
if(next == a.length){
Arrays.copyOf(a, a.length+1);
}
a[next] = s;
next++;
}
}
The easiest way would be to use an ArrayList (or any class that implements the java.util.List interface), as previously mentioned by Jon Skeet - it will do all the work for you.
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>.