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;
}
}
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.
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() + "]";
}
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;
}
}