I'd like to write a program which creates a set of objects in a loop....
(i.e.)
String newFirm = "empty";
for(int i=0; i<30; i++)
{
newFirm = "firm" + i;
firm newFirm = new firm();
}
and then of course I would need something like
stringToObject = "firm" + x;
stringToObject.type = "service";
stringToObject.size = 10000;
Obviously this code is fictional, but It expresses how I'd ideally create and call for objects. The nature of this program is such that the final number of firms (or other objects) are not known at the time of compiling.
Is there a method by which I can convert a given string into the name of an object (either to call or to create) as well as creating objects "on the fly"?
Sounds like a job for an ArrayList.
ArrayList<Firm> myList = new ArrayList<Firm>();
And in your loop,
Firm firm = new Firm();
firm.type = "service";
myList.add(firm);
And to get it,
Firm f = myList.get(index);
convert a given string into the name of an object
Your need is to refer an object with the string in your hand. I'll suggest Hashmap<String,Object>
Eg:- you have a String,
String name="object_name";
And your class is Firm. Now,
Hashmap<String,Firm> objs=new Hashmap<String,Firm>();// note:your for loop comes after this line
Firm new_firm=new Firm();
new_firm.type = "service";
new_firm.size = 10000;
objs.put(name,new_firm);
Now you can refer your object with the string in your hand as
objs.get("object_name");
Related
I have a CSV file that I am reading from. I have created a constructor with six arguments for initialising the six fields and a public string method to convert a string into the format I need.
public Hill(int number, String name, String countyName, double height, double latitude, double longitude) {
this.number = number;
this.name = name;
this.countyName = countyName;
this.height = height;
this.latitude = latitude;
this.longitude = longitude;
}
Now what I am trying to achieve is after opening the file and reading it, it creates the corresponding object and then to return the list of the items.
I was given an inital method of public static List<Hill> readHills()
I have commented out a line which i tried to create a new object from simply because I wasn't sure if I was doing it right, so i just printed out as a test to see what my code was doing and it seems that the new object line is redundant.
Currently my code is:
public static List<Hill> readHills() {
Scanner fileName = null;
try {
fileName = new Scanner(new File("C:/Users/TOSHIBA/Desktop/hills.csv"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
Scanner finalFileName = fileName;
List<Hill> list = new ArrayList<Hill>() {
{
for(int i = 0; i < 21; i++) {
String line = finalFileName.nextLine();
String[] splitted = line.split(",");
//add(new Hill(1, "", "", 100, 100, 100));
System.out.println(Arrays.toString(splitted));
}
}
};
return list;
}
In the code where I create the object I put a sample value but technically I want the 6 fields of the new object to be from the file I read. If i try adding the field names, i get a red line saying Non static method cannot be referenced from a static method
Where am i going wrong? And why is my line of code useless?
I continued trying to play with the code but can't get anywhere, I think my issue is not understand the method name i have been given; i.e. Why and what does public static List<Hill> readHills() do?
I tried using Hill newHill = new Hill( int number, String name, String countyName,double height, double latitude, double longitude); but can't since I cant reference a non-static field from a static context
For starters: this here
List<Hill> list = new ArrayList<Hill>() {
is valid syntax, but not at all what you want.
Just go for:
List<Hill> list = new ArrayList<>();
instead. What you are doing creates an anonymous inner class; and that is totally not required here; and instead leading to many of the issues you see.
Then: you have to turn your strings into the correct type:
String[] splitted = line.split(",");
gives you an array of String objects. You have to convert those; so that you can pass them to the constructor accordingly (your constructor expects an int value as first parameter, not a String for example!)
Hill hill = new Hill(Integer.parseInt(splitted[0]), splitted[1], ...
and so on.
And then you do:
list.add(hill);
But the tricky part is: such parsing relies on "correct" input. So you should be prepared for all kinds of error handling.
And beyond that: unless this is homework, then do not implement your own CSV parser. Use some existing library for that (see here for ideas). You see: doing correct CSV parsing, that works with all the subtle quirks of this format is not easy. You can easily spend hours on this task; to then find that the next CSV file you work with ... contains yet another (valid!) variation of CSV input that breaks your self-written parser. (believe me, I have been there)
And finally: if such things already overburden you, then the real takeaway is: accept that you are not there yet. Step back; get back into learning mode and understand all those basic Java things.
I am relatively new to Java and would like to know how to store variables separately from a single line of user input.
At the minute the user is prompted to enter football results in the following format
home_name : away_name : home_score : away_score
and I am using a while loop to continue to ask user for input until they enter "stop"
(while (input != "stop))
Once the loop is broken I would like my program to output a variety of data such as total games played, but I'm struggling to store the home_name, away_name etc.. especially if the user wishes to enter multiple lines of results.
Two mainstream ways to store a "record" are:
Maps
Data objects
A map is more generic:
Map<String,String> match = new HashMap<>();
match.put("home_name", "Alvechurch Villa");
match.put("away_name", "Leamington");
match.put("home_score", "0");
match.put("away_score", "6");
You can add a map to a list:
List<Map<String,String>> matches = new ArrayList<>();
matches.add(list);
... and retrieve them:
Map<String,String> match = matches.get(0);
System.out.println(match.get("away_score"));
A data object is more tuned to your data format, but you have to write the class yourself.
public class Match {
public String homeName;
public String awayName;
public int homeScore;
public int awayScore;
}
Now you can use this class:
Match match = new Match();
match.homeName = "Studley";
// etc.
You can add and retrieve these from lists too:
List<Match> matches = new ArrayList<>();
matches.add(match);
Match aMatch = matches.get(0);
This is simple, but it's considered bad practice to have public fields like this - it's better to get at them via methods. For brevity, here's a data class with only one field:
public class Player {
private String name;
public Player(String name) {
this.name = name;
}
public String name() {
return name;
}
}
Player neilStacey = new Player("Neil Stacey");
You can use the same technique with all the fields in Match.
(A common style is to name a method like this getName(), and also to have a setName(). I have used a different style and made the object immutable, in an effort to set a good example!)
One advantage of the data object is that it has different types for different fields: homeName is a String, homeScore is an integer. All the fields in the Map are Strings. You can get around this by using Map<String,Object> but then as a consumer you have to cast to the right type when you read.
String homeName = (String) match.get("home_name");
Data objects allow the compiler to do a lot of compile-time checking that helps you know your code is correct. If you use a map, you won't find out until runtime.
Prompt the user separately for each input.
System.out.println("home_name: ");
String hN = scan.next();
System.out.println("away_name: ");
String aN = scan.next();
System.out.println("home_score: ");
String hS = scan.next();
System.out.println("away_score: ");
String aS = scan.next();
In a small project I am working on I've gotten stuck. The user enters a command that may be "xp Speed", my command handler class finds that it wants to the XP value of the Speed Instance. In this case it needs to return the value of Skill.Speed.currentXP back to the user.
Small Part of the program:
//Example Instance initialization there is over 40 of these
Skill Speed = (new SkillSpeed(Skills.SKILL_SPEED,Skills.SKILL_SPEED_MODIFIER));
//Constructor for skill class
public Skill(String skillName, double modifier) {
this.name = skillName;
this.minLevel = Skills.MIN_SKILL_LEVEL;
this.Modifier = 1f;
this.currentLevel = (int)calculateLevel();
this.currentXP = 1;
this.leaderboard = getCurrentLeaderboard();
this.ID = getNextID();
}
Now, theres one way i could do this. by having a switch statement with case value being the string entered. However I'm sure having 40+ cases in one switch statement must be avoidable. The other theory I have had is creating a array of all current instances then iterating through that list, finding if the user inputted string is equal to the name of that instance, then returning the instance itself. This is what I came up with:
//method inside another classs that attempts to return the appropriate skill Instance
public Skill getSkillFromName(String Name) {
for(int i = 0; i < Skill.SkillArray.length; i++) {
final String SkillName = Skill.SkillArray[i].getName();
if(SkillName.equalsIgnoreCase(Name)) {
return Skill.SkillArray[i];
}
}
return null;
}
So here's what I need help with:
Creating a array of all initialized instances
Creating the method that will return Skill."InsertRandomInstanceDependingOnUserInputHere".currentXP
Fixing any problems you see in the getSkillFromName() method
Or perhaps I have overlooked a far easier way of doing this, and you can help me with that.
Thanks for the help,
BigDaveNz
If the names of the skills excatly match method names you might find the aswer at "How do I invoke a Java method when given the method name as a string?".
For finding instances by name you can still use Map's.
You can use a Map for this. E.g.:
Map<String, Skill> skills = new HashMap<String, Skill>();
To insert the values you put the values into the Map:
skills.put(skill.getName(), skill);
To retrieve your skill you can get the skill by name:
Skill skill = skills.get(name);
I wish to accomplish:
String []beef = new String[3];
beef[0] = "Water";
beef[1] = "Chicken";
beef[2] = "Paper";
String empo = Arrays.toString(beef);
if (empo.isEmpty()){
empo = "Nothing";
System.out.println(empo);
}else{
System.out.println(empo);
}
without having to create the string.
Something like:
String []beef = new String[3];
beef[0] = "Water";
beef[1] = "Chicken";
beef[2] = "Paper";
Arrays.toString(beef); //change beef to just a plain string
if(beef.isEmpty()||beef==""){
no = "Nothing";
System.out.println(beef);
How would one go about doing this?
You can't.
Java is a strongly and statically typed language. That means you have to tell it what type a thing will be when you declare it (strong typing), and you can't ever change it's type after that (static typing).
You will just have to create a new String.
You can create substrings with the same backing memory as the original string, but you can't create a string with the same backing memory as an array of strings. They're not stored in the same order so it's impossible to view the same memory both ways.
I have a Class named Group, it is described as follow:
public class Group{
public int identifier;
public int[] members;
public String name;
}
Now, I would like to create many different objects for this class, I mean for example 1000 groups each one has different number of members,
How can make it? I mean I would not make 1000 instructions like:
Group g1= new Group(....);
Thanks and best regards.
You need to research arrays, and loops:
Group[] groups = new Group[1000];
for (int i = 0; i < 1000; i++) {
groups[i] = new Group();
groups[i].identifier = XXX;
groups[i].members = new int[XXX];
...
}
Can you not use an array and a loop? E.g.:
...
public static final int ARRAY_SIZE = 1000;
...
Group arr[] = new Group[ARRAY_SIZE];
for( int i = 0; i < arr.size; i++ ) {
arr[i] = new Group();
}
If you want to assign different values to each of the 100 instances, then yes, you are facing a lot of typing. You can create the objects in a loop ( as Oli describes ), but to assign the different values you'll still end up doing
groups[0].identifier = 10;
groups[1].identifier = 44;
groups[3].identifier = 99;
etc etc.
You may be able to put the parameters in a file and wirte code to read the file and set the values in your object instances, but one way or another, unless the parameters can be generated by algorithm, you're going to end up typing them in