Adding a variable element to an array in java - java

String plants [] = {"Sunflower", "Pea Shooter", "Cherry Bomb", "Wall-Nut", "Potato Mine", "Snow Pea", "Chomper "};
int sunlight [] = {50, 100, 150, 50, 25, 175, 150};
for (int i = 0; i < plants.length; i++) {
System.out.println ((i+1) + "\t" + plants [i] + "\t" + sunlight [i]);
}
This prints out the array regularly, and this part works.
String addplant = IBIO.inputString ("\nWhich plant do you add? ");
int addsl = IBIO.inputInt ("How much sunlight do you add to that plant? ");
plants [] = {"Sunflower", "Pea Shooter", "Cherry Bomb", "Wall-Nut", "Potato Mine", "Snow Pea", "Chomper ", addplant};
sunlight [] = {50, 100, 150, 50, 25, 175, 150, addsl};
for (int i = 0; i < plants.length; i++) {
System.out.println ((i+1) + "\t" + plants [i] + "\t" + sunlight [i]); }
Similarly, I want a new array to be printed out based on the value the user inputs. The new element should appear at the end of the array.
I must get input using IBIO.input. It stores the user input into a variable.
However, what I tried does not work. Instead, it just says "VariableDeclaratorId expected after this token" and highlights the new array I made.
I am wondering how I would add a variable element to my array, and am unsure of how to do this. I tried googling many things but nothing seemed to have worked.

Arrays have a constant size, you can't resize them. Probably what you want is an ArrayList. Also you didn't ask but I noticed you have two arrays of related data correlated by index, this can get messy. Since plants are likely to have more than two kinds attributes I suggest using a class like this:
private class Plant {
String plant;
int sunlight;
public Plant(String plant, int sunlight) {
this.plant = plant;
this.sunlight = sunlight;
}
}
public void someMethod() {
ArrayList<Plant> plants = new ArrayList<Plant>();
plants.add( new Plant("Sunflower", 50));
plants.add( new Plant("Pea Shooter", 100));
...
for (int i = 0; i < plants.size(); i++) {
System.out.println((i + 1) + "\t" + plants.get(i).plant + "\t" + plants.get(i).sunlight);
}
}
Then if you delete Pea Shooters, you won't have the chance to forget deleting the sunlight element for Pea Shooters. Plus it's nice and clean if you decide to something like this:
private class Plant {
String plant;
int sunlight;
float soilPh;
public Plant(String plant, int sunlight, float soilPh) {
this.plant = plant;
this.sunlight = sunlight;
this.soilPh = soilPh;
}
}
public void someMethod() {
ArrayList<Plant> plants = new ArrayList<Plant>();
plants.add( new Plant("Sunflower", 50, 6.5f));
plants.add( new Plant("Pea Shooter", 100, 7f));
...
for (int i = 0; i < plants.size(); i++) {
System.out.println((i + 1) + "\t" + plants.get(i).plant + "\t" + plants.get(i).sunlight + "\t" + plants.get(i).soilPh);
}
}
Edit you need to import:
import java.util.ArrayList;

The better and the more "Java" way is to use List, because it has a better structure for manipulation of its items.
ArrayList<String> plants = new ArrayList<>(Arrays.asList("Sunflower", "Pea Shooter", "Cherry Bomb", "Wall-Nut", "Potato Mine", "Snow Pea", "Chomper"));
ArrayList<Integer> sunlight = new ArrayList<>(Arrays.asList(50, 100, 150, 50, 25, 175, 150));
Then you just add an item to the List with the method add() to the end.
plants.add(addplant);
sunlight.add(addsl);
Getting the wanted item works similar like with arrays. Use the get(index) method. The following method assume your lists of the same size.
for (int i=0; i<plants.size(); i++) {
System.out.println((i+1) + "\t" + plants.get(i) + "\t" + sunlight.get(i));
}
In the other case you would change the condition in your for-cycle to Math.min(plants.size(), sunlight.size()).
Also the usage of Map would be a good idea.
Map<String, Integer> myMap = new HashMap<>();
Adding items with the method put(...).

Arrays cannot be added to. You probably know this since you are reassigning the value of the array, putting in all the old elements plus the new one. This will cause problems because you've hard-coded it and the next time an item is added it will not contain any previously added new elements.
The best thing to do is to use a map, to store the plant and the amount of sunlight, like this:
Map<String, Integer> plantsAndSunlight = new HashMap<String, Integer>();
plantsAndSunlight.put("Sunflower", 50);
plantsAndSunlight.put("Peashooter", 100);
:
:
Then to add a new elements just add it to the end using the put function from above, passing in the elements you got from user inout:
String addplant = IBIO.inputString ("\nWhich plant do you add? ");
int addsl = IBIO.inputInt ("How much sunlight do you add to that plant? ");
plantsAndSunlight.put(addplant, addsl);

Related

returning an array filtered from an existing array

So here's the question I need to answer: Implement a method that takes a research area as an input and returns the names of scientists associated with that area.
I've got a lot of the base code necessary but am struggling because I am trying to filter out the array of scientist professions to only return the scientist whose profession is the specified input. What I need help with is finding a way to make a new array with only certain filtered scientists and excluding the unspecified scientist. Any idea on how to change the code to return an array of only certain scientists would be very helpful! The issue is in the CheckField method, and I'll put my code below of the program:
public class computerScientists {
String name;
String researchArea;
String contribution;
// Constructor
public computerScientists(String NM, String RA, String C) {
this.name = NM;
this.researchArea = RA;
this.contribution = C;
}
public static void main(String[] args) {
computerScientists[] personDatabase = {
new computerScientists("Katherine Johnson", "Mathematician", "Mathmetician for NASA during space race"),
new computerScientists("Kimberely Bryant", "Entrepreneur & Activist", "Founded black girls code"),
new computerScientists("Mark Dean", "Inventor and Engineer", "Helped design and release some of the first computers"),
new computerScientists("Marie Van Brittan Brown", "Inventor and Pioneer", "Pieneered and invented an audio-video alarm system"),
new computerScientists("Marian R Croak", "Engineer", "Helped develop the Voice Over Internet Protocol (VOIP)")
};
//int size = person1.length
for(int i=0; i<personDatabase.length; i++){
System.out.println("Innovator " + String.valueOf(i + 1) + ": \n");
System.out.println("Name: " + personDatabase[i].name + "\n"
+ "Research Area: " + personDatabase[i].researchArea + "\n"
+ "Contribution: " + personDatabase[i].contribution);
System.out.println();
}
checkField("Inventor", personDatabase);
}
public static computerScientists[] checkField(String researchField, computerScientists[] array1) {
computerScientists[] newArray1 = new computerScientists[array1.length];
//int difference = newArray1.length - array1.length;
for (int i=0; i < array1.length; i++) {
if (array1[i].researchArea.contains(researchField)) {
newArray1[i].researchArea = String.valueOf(array1[i]);
}
}
for (int j=0; j<newArray1.length; j++) {
System.out.println(newArray1[j].researchArea);
}
return newArray1;
}
}

(Java) How can I make a loop that will assign random names I've generated from an array to multiple strings?

Relatively new to Java, looking for a solution to a crucial part of a game I'm making for a class. The idea is to make a very simple stock market simulation game, but the problem is related to creating made-up company names. I have three arrays for the first, middle, and last names of companies. I'm trying to make some of these companies have one word names, others two, etc. So far I've used a random number generator and if/elif/else statement to simulate one, but I would like five of them and I would prefer a more efficient method of doing so. Here's the code:
import java.util.Random;
import java.io.*;
import java.util.*;
class Main {
public static void main(String[] args) {
// The code all goes in here
String[] companyFirstNames = {"Alpine", "Bear", "Bull", "Cuckoo", "Delta", "Dragon", "Echo", "Fighter", "Giant", "H20", "Indo", "Jared", "Jason", "Kicker", "Lodge", "Little", "Manzo", "Mint", "Neighbour", "Nelson", "Ossuary", "Open", "Private", "Poor", "Quick", "Quiant", "Reach", "Rebel", "Space", "Spear", "Titus", "Trebble", "Underdog", "Upper", "Vital", "Vert", "White", "Whistle", "X's", "Yuri's", "Yogurt", "Zebra"};
String[] companySecondNames = {" Science", " Technology", " Arts", " Research", " Laboratory", " Lodging", " Woodworking", " Fashion", " Oil", " Trading", " Investing"};
String[] companyLastNames = {" Limited", " Co.", " Corp.", " Corporation", " Ltd", " Institute", " Association", " Federation", " Firm"};
//Three arrays of random company name "pieces"
Random randomNamer = new Random();
//Used for getting random names & ints
int randomOne = randomNamer.nextInt(companyFirstNames.length);
int randomTwo = randomNamer.nextInt(companySecondNames.length);
int randomThree = randomNamer.nextInt(companyLastNames.length);
//Three ints that are given random values associated to the arrays
int numberOne = randomNamer.nextInt(100);
//Getting a random 0-100 number
String bigNameCompany = companyFirstNames[randomOne] + companySecondNames[randomTwo] + companyLastNames[randomThree];
String midNameCompany = companyFirstNames[randomOne] + companyLastNames[randomThree];
String smallNameCompany = companyFirstNames[randomOne];
//The three types of company names possible to produce
String companyOne;
String companyTwo;
String companyThree;
String companyFour;
String companyFive;
//The five companies I want to name
if (numberOne <= 45) {
companyOne = bigNameCompany;
//The first company name is random and big
} else if (numberOne <= 85) {
companyOne = midNameCompany;
//Two word name
} else {
companyOne = smallNameCompany;
//One word name
}
System.out.println(companyOne);
//printing the name of the first company
//Can i get a loop to do this more efficiently for 5 companies?
}
}
I'd encourage you to play around with it. That's the fun of programming is solving little puzzles like this, and there are a bunch of ways to do something like this. Here is one to give you some ideas:
Random randomNamer = new Random();
String[] companyFirstNames = { "Alpine", "Bear", "Bull", "Cuckoo", "Delta", "Dragon", "Echo", "Fighter", "Giant", "H20", "Indo", "Jared", "Jason", "Kicker", "Lodge", "Little", "Manzo", "Mint", "Neighbour", "Nelson", "Ossuary", "Open", "Private", "Poor", "Quick", "Quiant", "Reach", "Rebel", "Space", "Spear", "Titus", "Trebble", "Underdog", "Upper", "Vital", "Vert", "White", "Whistle", "X's", "Yuri's", "Yogurt", "Zebra" };
String[] companySecondNames = { " Science", " Technology", " Arts", " Research", " Laboratory", " Lodging", " Woodworking", " Fashion", " Oil", " Trading", " Investing" };
String[] companyLastNames = { " Limited", " Co.", " Corp.", " Corporation", " Ltd", " Institute", " Association", " Federation", " Firm" };
for (int i = 0; i < 5; i++) {
int chance = randomNamer.nextInt(100);
int firstIdx = randomNamer.nextInt(companyFirstNames.length);
int secondIdx = randomNamer.nextInt(companySecondNames.length);
int lastIdx = randomNamer.nextInt(companyLastNames.length);
String name = null;
if (chance <= 45) {
name = companyFirstNames[firstIdx] + companySecondNames[secondIdx] + companyLastNames[lastIdx];
} else if (chance <= 85) {
name = companyFirstNames[firstIdx] + companyLastNames[lastIdx];
} else {
name = companyFirstNames[firstIdx];
}
System.out.println(name);
}
You can create a simple method for that (and you don't need white spaces in your name Strings):
private final String[] companyFirstNames = {"Alpine", "Bear", "Bull", "Cuckoo", "Delta", "Dragon", "Echo", "Fighter", "Giant", "H20", "Indo", "Jared", "Jason", "Kicker", "Lodge", "Little", "Manzo", "Mint", "Neighbour", "Nelson", "Ossuary", "Open", "Private", "Poor", "Quick", "Quiant", "Reach", "Rebel", "Space", "Spear", "Titus", "Trebble", "Underdog", "Upper", "Vital", "Vert", "White", "Whistle", "X's", "Yuri's", "Yogurt", "Zebra"};
private final String[] companySecondNames = {"Science", "Technology", "Arts", "Research", "Laboratory", "Lodging", "Woodworking", "Fashion", "Oil", "Trading", "Investing"};
private final String[] companyLastNames = {"Limited", "Co.", "Corp.", "Corporation", "Ltd", "Institute", "Association", "Federation", "Firm"};
private final Random randomNamer = new Random();
private String generateRandomName() {
StringBuilder sb = new StringBuilder();
int size = random.nextInt(100);
int first = random.nextInt(companyFirstNames.length);
sb.append(companyFirstNames[first]);
if (size <= 85) {
int second = random.nextInt(companySecondNames.length);
sb.append(' ').append(companySecondNames[second]);
}
if (size <= 45) {
int last = random.nextInt(companyLastNames.length);
sb.append(' ').append(companyLastNames[last]);
}
return sb.toString();
}
Then you can do:
private List<String> generateNames(int numberOfNames) {
return IntStream.range(0, numberOfNames).mapToObj(i ->
generateRandomName()).collect(Collectors.toList());
}
Calling the last method will allow you to create as many names as you want:
List<String> names = generateNames(5)
System.out.println(names);
Output:
[White Trading Firm, Open Research, Indo Oil, Fighter Technology, Cuckoo Oil Corporation]
Your solution would probably work, but you could reuse your Random to decide whether a company name should have one, two or three words to make it more compact. This example would always generate a company with at least one name, while there's an equal probability for second and third:
final Random rnd = new Random();
final String[] companies = new String[5];
for(int i = 0; i < companies.length; i++) {
final int idx = rnd.nextInt(100);
companies[i] = companyFirstNames[idx%companyFirstNames.length]
+ (rnd.nextBoolean() ? companySecondNames[idx%companySecondNames.length] : "")
+ (rnd.nextBoolean() ? companyLastNames[idx%companyLastNames.length] : "");
}
You can use something like rnd.nextInt(2) == 0 or rnd.nextInt(3) == 0 to play with the odds of a longer company name instead of nextBoolean().
Edit
Something that may be worth thinking about is uniqueness - is it a problem if you happen to generate the same company name more than once? Depending on your strategy you could keep track of either the number or name you generate (probably in a Set), and regenerate if it already exists.

Adding an individual array list item to individual tile

I am currently trying to place individual items within an array list into individual tiles within a inventory GUI. All the tiles are set up and I can display each array list item individually within the console line.
This is the simple GUI:
This is my attempt so far.
HBox itemTile[] = new HBox[31];
for (int i = 0; i < 30; i++) {
Button deleteButton = new Button("Delete Item");
deleteButton.setOnAction((ActionEvent event) -> {
displayItems2(); //temp info to console - delete item code to be added
JOptionPane.showMessageDialog(null, "Item has been deleted", null, 1);
});
itemTile[i] = new HBox(new Label("Item: " + i + " "));
itemTile[i].setStyle("-fx-border-color: black;");
itemTile[i].setPadding(new Insets(5));
itemTile[i].getChildren().add(deleteButton);
itemTile[i].setAlignment(Pos.CENTER_LEFT);
itemTile[i].setStyle("-fx-background-color: #e5efff; -fx-border-color: black;");
this.getChildren().add(itemTile[i]);
}
}
private void displayItems2(){
this.getChildren().removeAll(this.getChildren());
displayInvStructure();
ArrayList<String> descs = InventoryManager.getInstance().getItemDescriptions();
for (int i = 0; i < descs.size(); i++) {
String retString = descs.get(i);
System.out.println("Array item is = " + " " + i + " " + retString);
}
//If i = itemTile[i]
//Add retString to itemTile[i]
}
How do I place each individual retString into each tile using the itemTile[i]?
I'm relatively new to coding and Java, so I have a sneaking suspicion I am over complicating things.
If you want to assign values to the itemTile array inside a method like displayItems2, there are two possibilities: 1) pass a reference to itemTile into displayItems2 or 2) make itemTile a class member.
Example 1 (pass a reference):
private void displayItems2(HBox itemTile) {
// [...]
itemTile[i] = descs.get(i);
}
Example 2 (class member):
class MyClass {
// [...]
HBox itemTile;
// [...]
private void displayItems2() {
// [...]
itemTile[i] = descs.get(i);
}
}

Earth Orbitting the Sun simulation Object Array not printing correctly java

I'm trying to simulate the Earths orbit around the sun making it print out its current position. I'm very new to java and unable to print the "newP" array correctly within the loop. At the moment I'm using-
System.out.println(Arrays.deepToString(newP));
I've also tried:
System.out.println(Arrays.toString(newP));
To no avail. I've definitely also imported java util array as well, I'm not sure why its not working. No other errors are appearing in the code either. The loop of the code is below:
do{
PhysicsVector[] y = new PhysicsVector[gravField.length];
y=copyArray(gravField);
for(int i=0; i<planets.length;i++){
newP[i] = planets[i].updatePosition(position[i], velocity[i], timeStep, gravField[i]);
}
for(int j=0; j<gravityObject.length; j++){
for(int l=0;l<gravityObject.length;l++){
if(j!=l){
newGrav[j].increaseBy(gravityObject[j].aDueToGravity(planetMass[l], newP[l], newP[j]));
}
}
}
for(int k=0; k<planets.length; k++){
newVel[k] = planets[k].updateVelocity(velocity[k], timeStep, y[k], newGrav[k]);
}
time+=timeStep;
double x = newP[0].getX();
double ap = newP[0].getY();
n.println(x+" "+ap);
System.out.println(Arrays.deepToString(newP));
}while (timeStep<(24*60*60*365.25));
The output I get when trying to print array in the loop is the below
[PhysicsVector#15db9742, PhysicsVector#6d06d69c, PhysicsVector#7852e922]
[PhysicsVector#15db9742, PhysicsVector#6d06d69c, PhysicsVector#7852e922]
[PhysicsVector#15db9742, PhysicsVector#6d06d69c, PhysicsVector#7852e922]
[PhysicsVector#15db9742, PhysicsVector#6d06d69c, PhysicsVector#7852e922]
The output I'm expecting is a list of vectors.
Thanks in advance.
You're seeing the output of the default toString() implementation as defined in the java.lang.Object class. To get a different output you have two main options
override toString() in the PhysicsVector class to return some kind of formatted String of the objects contents. That just involves adding a method to the PhysicsVector class like...
public class PhysicsVector {
....
#Override
public String toString() {
return "PhysicsVector[" + this.getX() + ", " + this.getY() + "]";
}
convert the PhysicsVector[] into a String[] using some kind of map. In Java8 this might look like
final String[] outputArray = Arrays.stream(newP).map((p) -> "PhysicsVector[" + p.getX() + ", " + p.getY() + "]").toArray()
If you're not using Java8 you might need to use a loop...
final String[] outputArray = new String[newP.length]
for (int i = 0; i< newP.length; i++) {
outputArray[i] = "PhysicsVector[" + newP[i].getX() + ", " + newP[i].getY() + "]";
}

find the most and least used string in an ArrayList

I am having trouble finding the most and least used String in an ArrayList. The program should go through a file of Strings and count how many multiple strings there are in the list. Then print the least and most used name in the list. The ArrayList Part is finished. It is just finding the most and least common name I am having trouble with. I have no idea how to even start with it. This is what I have found online but it is not working.
Map<String, Integer> dogNames = new HashMap<>();
for (Dog dog : dogs) {
Integer value = dogNames.get(dog);
if (value == null) {
value = 0;
}
value++;
dogNames.put(dog.getName(), value);
}
int leastCommon = Integer.MAX_VALUE;
String leastCommonName = null;
for (String name : dogNames.keySet()) {
int value = dogNames.get(name);
if (value < leastCommon) {
leastCommon = value;
leastCommonName = name;
}
}
System.out.println("Least common (" + leastCommon + ") is " + leastCommonName);
The problem with your code seems to be in this line:
Integer value = dogNames.get(dog);
Your map holds dog names (String), but you are getting the entry for the Dog, which does not exist! Thus, value stays 0 even if you've seen that name before. If you fix this, you code should work.
Instead of your loop for searching the least common name, you could also define a custom Comparator based on the counts in the map and then use Collections.min and Collections.max:
Comparator<Dog> comp = new Comparator<Dog>() {
#Override
public int compare(Dog o1, Dog o2) {
return Integer.compare(dogNames.get(o1.getName()), dogNames.get(o2.getName()));
}
};
System.out.println("least " + Collections.min(dogs, comp));
System.out.println("most " + Collections.max(dogs, comp));
With Java 8, you can make it even shorter, using Comparator.comparing:
List<Dog> dogs = ...
Map<String, Integer> dogNames = new HashMap<>();
dogs.forEach(dog -> dogNames.put(dog.getName(), dogNames.getOrDefault(dog.getName(), 0) + 1));
Comparator<Dog> comp = Comparator.comparing(d -> dogNames.get(d.getName()));
System.out.println("least " + Collections.min(dogs, comp));
System.out.println("most " + Collections.max(dogs, comp));
Or even shorter, using Collections.frequency instead of building your own map, and using that to compare. Note, however, that this will be wasteful if the list is very long, since this will search the list each time anew instead of caching the counts in the map.
List<Dog> dogs = ...
Comparator<Dog> comp = Comparator.comparing(d -> Collections.frequency(dogs, d.getName()));
System.out.println("least " + Collections.min(dogs, comp));
System.out.println("most " + Collections.max(dogs, comp));
Your code should look something like this...
Map<String,int> frequencyOfDogNames = new HashMap<String,int>();
for(String dogName:dogNames) {
if(frequencyOfDogNames.contains(dogName)) {
continue;
}
frequencyOfDogNames.put(dogName, Collections.frequency(dogs, "dogName"));
}
This will give you the map of all the names with the occurrences.
Now we should loop thought the map to see which one are the max and min...
int leastCommon = Integer.MAX_VALUE;
int mostCommon = 0;
String leastCommonName, mostCommonName;
int occurrence;
for(String dogName: frequencyOfDogNames.keySet()) {
occurrence = frequencyOfDogNames.get(dogName);
if(leastCommon > occurrence){
leastCommon = occurrence;
leastCommonName = dogName;
}
if(mostCommon < occurrence){
mostCommon = occurrence;
mostCommonName = dogName;
}
}

Categories