Using a String for an instance object name - java

I have this code which gets info from an other class but I have to add another line other code for every instance object.
public static int giveShipData(String shipName,int Data){
if(shipName.equals("Player")){i = Player.getData(Data);}
return i;
}
Is it possible to have something like:
public static int giveShipData(String shipName,int Data){
i = shipName.getData(Data);
return i;
}
Sorry if I am using the wrong terminology I am self taught and new.

I think you'd better to reconsider your design. If you have a ship name and ship data I assume you must have a Ship class which looks something like this:
public class Ship {
private String name;
private int data;
public Ship(String name, int data) {
this.name = name;
this.data = data;
}
public String getName() {
return name;
}
public int getData() {
return data;
}
}
Besides this class there should be a class like Shipyard:
public class Shipyard {
private Map<String, Ship> shipsByNameMap = new HashMap<String, Ship>();
public void registerShipByName(String name, Ship ship){
shipsByNameMap.put(name, ship);
}
public Ship getShipByName(String name){
return shipsByNameMap.get(name);
}
}
So, at first you invoke shipyard.getShip("Player") method to get ship object, than you can invoke ship.getData() method to retrieve ship data.

You might be able to do something like this...
int[] ships = new int[3]; // 3 ships
public void populateShips(){
for (int i=0;i<ships.length;i++){
ships[i] = giveShipData(shipname,data);
}
}
public int giveShipData(String shipName,int data){
return shipName.getData(data);
}
This would allow you to create any number of ships, just increase the size of the ships[] array to be however many ships you want.
Is this kinda what you're after?

As per your code "shipName" is a string...and it does not have getData() method. And why are you passing Data to the getData()... You could instead write something like this-
i = ClassObj.getData(shipname);
and in the method getData return the info regarding the "shipname".

Related

Is there a way to efficiently audit statistics attributes of objects in Java?

Say I have a class Person, and I created 10 instances of Person, and each person has several different attributes, such as enum Gender{MALE, FEMALE}, enum Profession{CEO, POLICE, TEACHER}, etc.
And I somehow have to randomly create many persons with random attributes and use a dedicated class to audit the statistics of created persons' attributes.
So, eventually, I need to generate a list of attributes with some statistics accordingly, such as, "FEMALE: [number], POLICE: [number],...".
Currently, I'm planning to add all kinds of the persons' attributes count, as a bunch of new attributes to the audit class, such as, "femaleCount int, policeCount int, ..." then manipulate the counts based on generated persons.
But, I got 10-ish attributes for each person, so I wonder if there is a better way to do this.
Thanks for your reading.
One possible approach is below, but do not say that it's the only one neither the best.
It's only depends of the purpose and your design.Other option maybe it's to store all Persons in a data-structure List and just compute the statistic based on data at a certain time (have also update/delete here)
Version where only add is counting ...
public class Statistic
{
private static Statistic s=null;
public int countPerson;
public int countMale;
public int countFemale;
public static Statistic getInstance()
{
if(s==null)
s = new Statistic(0, 0, 0);
return s;
}
public static Statistic getInstace(int cP,int cM, int cF)
{
if(s==null)
s = new Statistic(cP, cM, cF);
return s;
}
//do whatever init wanted
private Statistic(int cP,int cM, int cF)
{
countPerson = cP;
countMale = cM;
countFemale = cF;
}
public String toString()
{
return "Total="+countPerson+", Male="+countMale+", Female=" + countFemale;
}
}
...
public class Person
{
public int id;
public String name;
public Gender g;
public Profession p;
public enum Gender{MALE, FEMALE};
public enum Profession{CEO, POLICE, TEACHER}
Person(int id,String name, Gender g, Profession p)
{
this.id = id;
this.name = name;
this.g = g;
this.p = p;
Statistic.getInstance().countPerson++;
if(g.equals(Gender.MALE))
{
Statistic.getInstance().countMale++;
}
else
{
Statistic.getInstance().countFemale++;
}
}
}
...
public class TestStat {
public static void main(String[] args)
{
//cPersons,cMale,cFemale - init
Statistic.getInstace(10, 5, 5);
System.out.println(Statistic.getInstance());
new Person(1,"Male",Person.Gender.MALE, Person.Profession.TEACHER);
System.out.println(Statistic.getInstance());
new Person(2,"Female",Person.Gender.FEMALE, Person.Profession.CEO);
System.out.println(Statistic.getInstance());
}
}
Output
//custom start from (10,5,5) based on Singleton Custom Constructor
Total=10, Male=5, Female=5
//start update counters
Total=11, Male=6, Female=5
Total=12, Male=6, Female=6
Thinking twice maybe it's better to keep a List with Persons on Singleton
and make each time a new Computation - from Singleton instead on Person.
About Delete a person which can be translated in "moving from a Company to other" and then it's not to be reflected on Statistic.
Even so, on current you could add a delete method on person which could be reflected with adjust Statistic with minus and Person-Instance with null.
Further, it's up to you to update design as wanted.

Getting Variables From Java constructor

I'm new to Java programming, sorry if this is a dumb question.
I find it hard to word this question properly, but I have an assignment to create a aircraft class that can make aircraft land, takeoff etc. And need to test it using Testclass. When the new object are entered it automatically assigns a unique ID to the aircraft in the constructor.
I can do this using a instance method fine as it has a return value which is returned to to Testclass. The question wants me to do this in the constructor itself, however, the constructor never returns anything. So the variable never gets sent to the Testclass. I clearly am not understanding OOP properly. Even when I try to just use a getter method to get the ID created in the constructor it gives me the initialized variable before the the constructor has worked on this. This is the code I have so far and its completely wrong I know but if someone could point me in the right direction or tell me how to word this question better it would be a massive help.
// I need to enter 3 aircraft into the system in the testclass
public class Aircraft {
private int aircraftID;
private static int lastID;
private String airportcode;
private int ID = 100;
private int count;
public Aircraft(int a, int b, int c){
// Constructor
// Assign ID
this.ID = a;
lastID = ID;
ID++;
this.ID =b;
lastID = ID;
ID++;
}
}
OK, you want to create an Aircraft that has an automatically-assigned unique identifier, and can take off and land. That implies you need a field for tracking the identifier, a field for tracking whether it's in the air (or not), and methods for the take off and land operations. You also need a static field for generating the unique identifiers. (Note that this implementation isn't thread safe.)
private class Aircraft {
private static int staticId = 0;
private int uniqueId = 0;
private boolean onGround = true; // Aircraft start on the ground in this implementation
public Aircraft(){
this.uniqueId = staticId; // putting this line first makes uniqueId zero-indexed in effect
staticId++;
}
public void land(){
onGround = true;
}
public void takeoff(){
onGround = false;
}
public boolean isFlying(){
return !onGround; // If it's not on the ground, it's flying
}
public int getUniqueId(){
return uniqueId;
}
}
Unit tests checks all of the methods and expected functionality of the class in question:
import org.junit.Test;
import static org.junit.Assert.*;
import Aircraft;
class Testclass {
private final Aircraft aircraft = new Aircraft();
#Test
public void hasId(){
aircraft.getUniqueId() >= 0;
}
#Test
public void canLand(){
assertTrue(aircraft.land());
}
#Test
public void canTakeOff(){
assertTrue(aircraft.takeOff());
}
#Test
public void checkFlightOperationsAreTrackedCorrectly(){
aircraft.land();
assertFalse(aircraft.isFlying());
aircraft.takeOff();
assertTrue(aircraft.isFlying());
}
}
As pointed out a constructor does not return anything (the simplified version is that with new it returns an object instance). I am kinda guessing at what you are trying to acomplish, but I'll have a go anyways. It seems to me that you are trying to cram the construction of 3 objects into one constructor - which is why your constructor has 3 parameters. Also you are playing havoc with the IDs.
I have removed all the variables that I didnt quite understand, leaving only ID that increments with each instantiated Aircraft. The #Override is mainly just for show.
public class Aircraft {
private int aircraftID;
private static int lastID = 0;
#Override
public String toString(){
return "Aircraft_" + this.aircraftID;
}
public Aircraft() {
lastID++;
this.aircraftID = lastID;
}
}
I took the liberty and wrote the TestClass just to see if we have the same thing in mind. Again the printAircraft() method is for show.
public class TestClass {
private List<Aircraft> aircrafts;
public TestClass(){
aircrafts = new ArrayList<>();
}
public void addAircraft(Aircraft a){
aircrafts.add(a);
}
public void printAircraft(){
Iterator<Aircraft> it = aircrafts.iterator();
while(it.hasNext()){
System.out.println(it.next().toString());
}
}
}
and to test it, we create and instance of TestClass add 3 Aircraft instances and print out the contents
public static void main(String[] args) {
TestClass tc = new TestClass();
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.addAircraft(new Aircraft());
tc.printAircraft();
}
This would be the case if you are to write the TestClass. If that is given, it would help to know what it looks like - maybe that would help us understand better.

Define static data in separate place to reuse

I have list of string data that are not change during any operation inside my program. But i need to access those data in several places by using key.
As a example: (1,ANN)(2,ALEX)(3,ANDROW)
Is there any way to store these data in separate class.Can I use java enum for this. thank you
With the use of enum you can implement something like below:
public enum Name {
ONE {
#Override
public String getName() {
return "ANN";
}
},
TWO {
#Override
public String getName() {
return "ALEX";
}
},
THREE {
#Override
public String getName() {
return "ANDROW";
}
};
public abstract String getName();
}
Then you can get the the names :
System.out.println(Name.ONE.getName());
This is really a good candidate for using Map. Where you can use your numbers as keys and String's as values.
https://docs.oracle.com/javase/tutorial/collections/interfaces/map.html
Map<Integer, String> map = new HashMap<Integer,String>();
Map<Integer,String> is one option and if key is also constant you could define string variable like
public static final string ONE = "ANN";
public static final string TWO = "ALEX";
A different way to use enums to define a statically mapping:
public enum Names {
ONE("ANN"),
TWO("ALEX"),
THREE("ANDREW");
private final String name;
private Names(String name){
this.name=name;
}
public String getName() {
return this.name;
}
}
This is only applicable to real-static values (change to values does mean a code change), but you can easily define multiple properties as well.
You can do the following:
import java.util.HashMap;
public class Main {
static HashMap<Integer,String>data = new HashMap<>();
public static void main(String[] args) {
// write your code here
data.put(data.size(),"ALEX"); // if you want 1-based indexing,
data.put(data.size(),"ANDROW"); // then use data.size()+1
data.put(data.size(),"ANN"); // instead of data.size()
for (int i = 0; i<data.size(); i++){
System.out.println(i+" : "+data.get(i)); // use i+1 if 1-based indexing
}
}
}

Best way to store collection of objects in Java?

I am creating a dump Java app for student information system for learning and implementing OOPS Concepts like inheritance, abstraction, polymorphism and encapsulation.
What I am doing is, I have created Faculty Class, Student Class and a College Class. Now i want to add new faculty in College. So my approach is to create a method in College class i.e. addFaculty(Faculty f) and fireFaculty(Faculty f), now i want to add Faculties in College class.
Whats the best way to do it? How do i store list of Faculty Object in College Object. Because i can add more than one faculty and more than one student in college.
Whats the best approach to solve this problem in OOPS?
Here is College.java code which i have implemented, it works fine but is this the best way i can solve it?
public class College
{
String name;
String location;
String courses[];
HashMap<String,Faculty> faculties;
int noOfFaculties = 0;
int noOfStudents = 0;
public College(String name,String location,String courses[])
{
this.name = name;
this.location = location;
this.courses = courses;
faculties = new HashMap<>();
}
public void addFaculty(Faculty faculty)
{
faculties.put(faculty.getName(),faculty);
}
public void printFaculties()
{
Set<String> set = faculties.keySet();
if(set.size()>0)
{
for(String s:set)
{
System.out.println(faculties.get(s).getName());
}
}
else
{
System.out.println("No Faculties Currently Working");
}
}
public void fireFaculty(Faculty faculty)
{
faculties.remove(faculty.getName());
}
public String getName()
{
return name;
}
public String getLocation()
{
return location;
}
public String[] getCourses()
{
return courses;
}
}
If you cannot have duplicates use HashSet<Faculty> if you dont mind use a List<Faculty>.
Example:
class College {
private List<Faculty> listFactories = new ArrayList<>(); // dupes allowed
private Set<Faculty> setFactories = new HashSet<>(); // no dupes allowed
}
Check collections API.
There's a ton of ways you can do it. Probably the easiest way to handle storing a collection of objects is by using one of the Collections provided by Java. For beginners, probably the easiest one to understand is an ArrayList, which is basically an array that grows in size dynamically depending on the amount of objects in the collection.
So, as an axample, your code might be something like this:
public class College
{
private ArrayList<Faculty> faculty;
public College()
{
faculty = new ArrayList<Faculty>();
}
public void addFaculty(Faculty f)
{
faculty.add(f);
}
public void fireFaculty(Faculty f)
{
faculty.remove(f);
}
}
imho It depends what kind of services College college offers. If I were coding, I would start with:-
List<Faculy> faculties = new ArrayList<>();
....
public void addFaculty(Faculty f) {
faculties.add(f);
}
//... etc
And change to an altearnative later if needed.

Java android multidimensional array (hash maybe) with string and nested class

I'm trying to track class stats for an android game I'm working on.
public static class characterClasses {
public String class_name;
public int base_hp;
public int base_attack;
public float base_defense;
}
I want to access these directly by name so I won't have to iterate over them repeatedly. From my research it looks like a hashmap or map would be what I need but everything I've seen is only for a single key/value pair. I need to access each stat value directly by class and value, something like
classList.get("warrior").get("base_hp");
Can someone point me in the right direction?
You are correct to think of using HashMap. You can use the characterClass String names as keys and the characterClasses as values. You can then use your getter methods to access your specific fields i.e.
classList.get("warrior").getBase_HP();
You could also forget maps entirely since these stats seem constant by using inheritance
public class Character {
int hp;
int attack;
int defense;
public Character (int hp, int attack, int defense) {
this.hp = hp;
this.attack = attack;
this.defense = defense;
}
public int getHP() {
return hp;
}
...
}
For your Character subclasses, you can preset those values in the constructor
public class Warrior extends Character {
public Warrior() {
super(2, 10, 8);
}
public int getHP() {
return super.getHP();
}
}
public class Wizard extends Character {
public Wizard() {
super(10, 3, 1);
}
public int getHP() {
return super.getHP();
}
}
This way all your Warrior and Wizard Objects will have the same stats that can be accessed any time simply by invoking their getters.

Categories