I'm trying to store objects that have a username and password from the class "Driver" into an array list. When I try to print every value in the array to test whether they're being stored, it only prints the last value declared, numerous times. I have tried nearly every other solution on thee forums related to this issue and it just wont work :(
Code below:
package eDepotSystem;
import java.util.ArrayList;
public class Driver {
protected static String driverUserName;
protected static String driverPassWord;
public Driver (String userName, String passWord) {
driverUserName = userName;
driverPassWord = passWord;
}
public static void driverArray() {
ArrayList<Driver> driverList = new ArrayList<Driver>();
Driver driver = new Driver(driverUserName, driverPassWord);
driver.setUserName("driver1");
driver.setPassword("123");
driverList.add(driver);
driver = new Driver(driverUserName, driverPassWord);
driver.setUserName("driver2");
driver.setPassword("321");
driverList.add(driver);
Driver tempDriver = new Driver(driverUserName, driverPassWord);
for (int i = 0; i < driverList.size(); i++) {
tempDriver = driverList.get(i);
System.out.println(tempDriver);
}
}
public void setPassword(String password) {
driverPassWord = password;
}
public static String getUserName() {
return driverUserName;
}
#Override
public String toString() {
return driverUserName + driverPassWord;
}
}
I don't know whether my loop is wrong or the way I'm declaring the objects is wrong? Any help would be grand and thanks in advance!
your field variables should not be static.
It is being shared by all instances of Driver class (ie objects), hence it is printing the last value which you added.
Problem 1:
Your "instance variables" (username and password) are static. Therefore you only have one instance of them. If you print them out you must always get the same value.
Problem 2:
You only add one object. You add it once, change it's values and add it a second time. If you print it out you must get the same values ... even if you remove the statickeywords.
You should instead try something like this:
package eDepotSystem;
import java.util.ArrayList;
import java.util.List;
public class Driver {
private final String driverUserName;
private final String driverPassWord;
public Driver (String userName, String passWord) {
driverUserName = userName;
driverPassWord = passWord;
}
public static void driverArray() {
List<Driver> driverList = new ArrayList<Driver>();
driverList.add(new Driver("drv1", "pw1"));
driverList.add(new Driver("drv2", "pw2"));
for (Driver tempDriver : driverList) {
System.out.println(tempDriver);
}
}
}
The static keyword forces the driverUserName and driverPassWord variables to be instantiated only once in memory. While they are not constants, it makes any further additions to your list reference that first and only instance in memory, hence why it keeps showing the same value.
https://docs.oracle.com/javase/tutorial/java/javaOO/classvars.html
Related
I'm really new to Java and programming in general (~3 weeks of experience) so sorry if this question is obvious for you guys. I tried searching for answers here but couldn't find any that fit my specific problem. And yeah it's for school, I'm not trying to hide it.
Here I'm supposed to write an object method that returns the string contained in the object oj, in reverse. I do know how to print a string in reverse, but I don't know how I should call the object since the method isn't supposed to have any parameters.
import java.util.Random;
public class Oma{
public static void main(String[] args){
final Random r = new Random();
final String[] v = "sininen punainen keltainen musta harmaa valkoinen purppura oranssi ruskea".split(" ");
final String[] e = "etana koira kissa possu sika marsu mursu hamsteri koala kenguru papukaija".split(" ");
OmaMerkkijono oj = new OmaMerkkijono(v[r.nextInt(v.length)] + " " + e[r.nextInt(e.length)]);
String reve = oj.printreverse();
System.out.println(reve);
}
}
class OmaMerkkijono{
private String jono;
public OmaMerkkijono(String jono){
this.jono=jono;
}
public String printreverse(){
//so here is my problem, i tried calling the object in different ways
//but none of them worked
return reversedstringthatdoesnotexist;
}
}
You just need to add this to your "printreverse" method :
new StringBuilder(this.jono).reverse().toString()
With this, when you call the method with the object "oj":
String reve = oj.printreverse();
After the previous line, "reve" must contain the value of the String reversed.
Olet hyvä, moi moi!
To revers a String use StringBuilder and reverse()
public String printreverse(){
return new StringBuilder(jono).reverse().toString();
}
To access private attributes from outside the class you use what are called accessors and mutators, aka getters and setters.
You just need a basic getter that also reverses the string.
public class MyObject {
private String objectName;
MyObject(String objectName) {
this.objectName = objectName;
}
public String getObjectName() {
return objectName; // returns objectName in order
}
public String getReversedObjectName() {
return new StringBuilder(objectName).reverse().toString();
}
public static void main(String[] args) {
MyObject teslaRoadster = new MyObject("Telsa Roadster");
System.out.println(teslaRoadster.getObjectName());
System.out.println(teslaRoadster.getReversedObjectName());
}
}
Output:
Telsa Roadster
retsdaoR asleT
I have this class and need to know which constructor is needed to create an object that may immediately use all its methods without error
public class Robot {
private boolean fuelEmpty = true;
private int roboID;
private String greeting;
private String securityProtocol;
//insert robot constructor here
public void destroyAllHumans(){
while (fuelEmpty == false) {
//robot begins to destroy all humans
}
}
public int getRoboID(){
return roboID;
}
public void greet(){
System.out.println(greeting);
}
public void setSecurityProtocol(String proto){
securityProtocol = proto;
}
}
For example should look like this:
public Robot(int id, String greet) {
roboID = id;
greeting = greet;
}
or this:
public Robot(int id, String greet) {
roboID = id;
greeting = greet;
fuelEmpty = false;
}
or:
public Robot(boolean full, int id, String greet, String proto) {
roboID = id;
greeting = greet;
fuelEmpty = full;
securityProtocol = proto;
}
Which of these (or something else different) is needed so that all the other methods can run without an error?
You can overload the constructor as much as you need, the important thing is
the object gets properly instantiated after you create a new one...
a way can be:
public Robot() {
this(false, 0, "", "");
}
public Robot(int id) {
this(false, id, "", "");
}
public Robot(boolean fuelEmpty, int roboID, String greeting, String securityProtocol) {
this.fuelEmpty = fuelEmpty;
this.roboID = roboID;
this.greeting = greeting;
this.securityProtocol = securityProtocol;
}
so look how all other constructors will at the end call internally the
public Robot(boolean fuelEmpty, int roboID, String greeting, String securityProtocol)
that will give you the waranty that no matter which constructor is invoked, the Robot is fully created and can invoke all those methods without crashing
The solution works like this:
you look at each of your methods
you check which fields each method is using
you check more closely, if the method breaks when that field has its default value (like null for Objects, or false for booleans)
When you do that for all methods, you get a list of those fields that you need to initialize somehow. Then you could go forward and define a corresponding constructor.
But of course, that is the wrong approach.
The real answer goes like this: you don't put fields into a class because you can. You add them because they are required so that this class can implement the requirements (responsibilities) that you want it to implement. Meaning: you focus on the methods that your class should provide. Then you clarify which fields you need in order to implement these methods.
In other words: you have exactly those fields in your class that your class needs. If you have fields in there that go unused - then you get rid of them.
I need an entity called DynamicEntity for example, in which I must define an UNKNOWN number of variables with theyr setters and getters. The variables must have a name I want to give them, so for this i got:
The main class:
public class Main {
public static void main(String[] args) {
DynamicEntity dynamic = new DynamicEntity();
dynamic.parseVariable("int");
}
}
And the DynamicEntity class:
public class DynamicEntity {
public void parseVariable(String text) {
String[] tokens = text.split("-");
String variableType = tokens[0];
String variableName = tokens[1];
if (variableType.equals("int")) {
int variableName = 0;
}
}
}
Definetly the variableName will not be accepted due to its defined already.
The thing is that i dont want the variable inside the IF to be called variableName, I want the variable to be called as the whats inside the tokens[1].
And of course creating setters and getters for every new variable added, which i have no clue what to do for this.
You can benefit from the Map structure. Where as the key you put the name of your member and as value the value for it.
A simple example of concept:
class Dynamic {
private final Map<String,Object> members = new HashMap<>();
public void setMember(String name, Object value) {
members.put(name,value);
}
public Object getMember(String name) {
return members.get(name);
}
}
How to print any class instance in Java? Similar to JSON.stringify() in Javascript. Not necessary JSON, any format of output will do.
public class User {
public String name, password;
public int age;
public ArrayList<String> phones;
public static void login() {
//do something
}
}
User X = new User;
X.name = "john connor";
X.password = "skynet";
X.age = "33";
X.phones.add("1234567");
X.phones.add("7654321");
System.out.println(printClass(X))
Should output something like:
{ name:"john connor", password: "skynet", age: "33", phones:
["1234567", "7654321"], login: void function() }
You can use Apache's commons-lang's ToStringBuilder.reflectionToString
Of course, reflection is slow, so only do this with your test code. for normal use, please use eclipse's "Source" menu -> generate toString() (or intellij's generate toString()) which gives you a decent string.
There could be many ways to achieve what you need. Though i would be interested in why you need.
Override the toString() method.
see: http://www.javapractices.com/topic/TopicAction.do?Id=55
If the generation algorithm gets too long, then consider a separate class say UserPrettyPrinter.
public interface UserPrettyPrinter {
string print(User);
}
public class PrintUserInJSON implements UserPrettyPrinter {
string print(User user) {
//implement the algo here
}
}
you can also implement:
public class PrintUserInXML implements UserPrettyPrinter {
string print(User user) {
//implement the algo here
}
}
Either in conjugation to number-2 or as a standalone class, you can write
public class PrintObjectBasicAlgo {
String print(Object obj) {
/* i write pseudo code here. just ask if you cannot implement this
this would help: http://docs.oracle.com/javase/tutorial/reflect/class/classMembers.html
Class class = Obj.getClass();
Filed[] allVariables = class.getAllFieldsByReflection();
ArrayList<String> keys = new ArrayList<String>;
ArrayList<String> values = new ArrayList<String>;
for(Field field : allVariables) {
Object value = reflectionGetValueOfField( field, obj );
keys.add( field.getName());
values.add(value.toString());
}
now that you have the keys and values, you can generate a string in anyway you like
*/
}
}
You may see Visitor Pattern. it might be helpful.
You have two options here. The simple one is just to override the toString function for your class. I dont see why you dont do this really. In this case its as simple as
String toString(){
return "{ name:\""+name+", password: \""+passowrd....
}
The second option is to use reflection. This would be slightly (though not really) better if you had some sorta external class used for "printing classes". The pseudo code for that would be
StringBuilder s = new StringBuidler();
for(Field f : fields){
s.append(f.getName() + "\" :\"" + f.get()+ "\"");
}
return s.toString();
However this would be costly as reflection always is. Also if you just properly override the toString functions in the first place your printClass function could literally just be
String printClass(Object o){ return o.toString();}
Which of course again begs the question of why do you need a printClass function?
One option is to use Google Gson.
import java.util.ArrayList;
import java.util.List;
import com.google.gson.Gson;
class Project {
private int year = 1987;
private String name = "ROBOCOP-1";
private boolean active = false;
private List<String> list = new ArrayList<String>() {
{
add("PROTECT THE INNOCENT");
add("UPHOLD THE LAW");
add("SERVE THE PUBLIC TRUST");
add("CLASSIFIED");
}
};
}
public class GsonExample {
public static void main(String[] args) {
Project obj = new Project();
Gson gson = new Gson();
String json = gson.toJson(obj);
System.out.println(gson.toJson(obj));
}
}
How would you go about creating a class like this:
public class tmUser {
private String Username;
private int wHours;
static int numUsers;
public tmUser(){
Username = "";
wHours = 0;
}
public tmUser(String U, int H){
Username = U;
wHours = H;
}
public void setUsername(String U){
Username = U;
}
public void setwHours(int H){
wHours = H;
}
public String getUsername(){
return Username;
}
public int getwHours(){
return wHours;
}
public static void initnumUsers(){
numUsers = 0;
}
public static int getnumUsers(){
return numUsers;
}
}
and then printing all of tmUser instances Username variable? in maybe a for each loop? I'm hoping for something like:
for each(tmUser){
System.out.println(Username);
}
This is for a menu in a program which displays all created users usernames.
You almost had it:
List<TmUser> tmUsers = ...
for(TmUser user : tmUsers) {
System.out.println(user.getUsername());
}
You would also want to capitalize tmUser into TmUser.
When you create a tmUser add it to a collection like
List<TmUser> tmUsers = new ArrayList<TmUser>();
TmUser tmUser = new TmUser(username, hoursWorked);
tmUser.add(tmUser);
// later
for(TmUser tmUser: tumUsers)
System.out.println(tmUser.getUsername());
You need to store all of tmUser instances somewhere first. You could do it this way:
public class tmUser {
...
public static List<tmUser> USERS = new ArrayList<tmUser>();
public tmUser() {
...
USERS.add( this );
}
and then printing:
for (tmUser user : tmUser.USERS) {
System.out.println(user.getUsername());
}
The 3 current answers are basically the same. Just wanted to add that if the class defined a toString() that returned the user name, it would not be necessary to add the .getUsername() method call, since System.out.println(Object) will automatically call the toString() method.
Whether this could work for your use case is debatable. The toString() method would normally provide more data on the object.
As the answers already posted indicate, this would involve maintaining some sort of data structure that holds references to all instances of tmUser (e.g. a List<tmUser>).
This would mean that a reference to each and every instance ever created will always be held there, they will never be garbage collected. You could explicitly remove them when you decide an instance is no longer needed, but then you would have to keep track of the life cycle of all instances, and basically end up doing memory management yourself.