I have two Classes.
one DAO that has an Arrraylist of Users (user is instace of User class)
and one method in another class that checks if there is a user with our input name or not
How can I use Hashmap (usernames, User) instead of Arraylist of Users?
public class UserDAO {
private static UserDAO instance;
private static String fileName = "sources/users.aaa";
//--------------------------------------------------------
private UserDAO(){
}
//--------------------------------------------------------
public boolean storeUsers(ArrayList<User> Users){
return IOFile.writeObject(Users, fileName);
}
//--------------------------------------------------------
public ArrayList<User> getUsers(){
ArrayList<User> Users = (ArrayList<User>) IOFile.readObject(fileName);
return Users;
}
//--------------------------------------------------------
public static UserDAO getInstance(){
if(instance == null)
instance = new UserDAO();
return instance;
}
}
and one method in another class that checks if there is a user with our input name or not:
User user = new User(firstName, lastName, userName, password);
ArrayList<User> users = UserDAO.getInstance().getUsers();
for (User user2 : users) {
if (user.equals(user2)){
system.out.println ("Error!!");
return;
}
}
users.add(user);
UserDAO.getInstance().storeUsers(users);
In this case, since you're just trying to check if the user exists, you could use a HashSet. A set has constant time lookups. So instead of your loop, it would just be users.contains(user).
You could use a map if you were looking up by something other than the actual User object, e.g. a mapping of names to users.
In either case, if you're using collection where you're checking contains, you must implement both equals and hashCode properly.
Related
Image of variable hierarchy (Please Check)
I want this specific variable to be a list of usernames, and each of these users will have some bookings... I tried adding an arraylist within an arraylist but that doesnt allow the user to name the usernames, they have to be predefined, please give me a method to do this.
You can store any kind of object in an ArrayList.
You could define your own class Booking that contains information about a booking:
public class Booking {
// ... whatever information is necessary for a booking
}
And then define a class User that contains information about a user, including a list of bookings:
public class User {
private String name;
private List<Booking> bookings = new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Booking> getBookings() {
return bookings;
}
// ... other methods as necessary
}
And then you can make an ArrayList of User objects, where each User object contains a list of Booking objects:
List<User> users = new ArrayList<>();
I need to make a method getUserById witch will return 1 user by its id. I think that I need to use HashMap so here is my method :
public class UserDao {
private static final String SELECT_USERS = "select * from users_Alana";
public static List<User> getUsers(JdbcTemplate jdbcTemplate){
return jdbcTemplate.query(SELECT_USERS,new UserMapper());
}
private static class UserMapper implements RowMapper<User> {
#Nullable
public User mapRow(ResultSet resultSet, int i) throws SQLException {
User user = new User();
user.setId(resultSet.getInt("id"));
user.setName(resultSet.getString("name"));
user.setGender(resultSet.getString("gender"));
user.setAge(resultSet.getInt("age"));
return user;
}
}
public static void getUserById(int number) throws SQLException {
HashMap<Integer,User> getUser = new HashMap<Integer, User>();
if (getUser.containsKey(number)) {
System.out.println(getUser);
}
}
}
I call this method in a main class by UserDao.getUserById(2); Also I have a class User (with int id, age; String name, gender;) Constructor, getters and setters in it.
The result is nothing. How to solve it?
To get the user by id, I don't think you need a HashMap you can just use :
public static void getUserById(int id) throws SQLException {
UserDao dao = new UserDao();
List<User> users = dao.getUsers(jdbcTemplate);//This return a List or users
User user = user.stream()
.filter(u -> u.getId() == id)// filter the user by id
.findFirst()// if find then return the first
.orElseGet(User::new);// else return new User()
}
But it can be better to create a second query to get user by id :
private static final String SELECT_USERS_BY_ID = "select * from users_Alana WHERE id = ?1";
You need to return the User object from the getUser
public static User getUserById(int number) throws SQLException {
HashMap<Integer,User> getUser = new HashMap<Integer, User>();
return getUser.get(number);
}
You do need to populate the HashMap with the values though
I have a simple Class with a inner class.
I want to set the following:
users[0][user_id]=8
users[1][user_id]=25
This is class:
public class ChatRequest {
private List<Userbean> users;
public List<Userbean> getUsers() {
return users;
}
public void setUsers(List<Userbean> users) {
this.users = users;
}
public static class Userbean {
private int user_id;
public int getUser_id() {
return user_id;
}
public void setUser_id(int user_id) {
this.user_id = user_id;
}
}
}
I tried it but without success.
How can I set the user id of the first user to 8 and the user id of the second user to 25?
These are java basic. Before refer to the Android SDK or something else please take a look into a java learning book/page.
However. Your "models" (or simple classes) are correct. To use these classes (and set the IDs you want) you need some instance of a UserBean first.
final ChatRequest.Userbean user0 = new ChatRequest.Userbean()
final ChatRequest.Userbean user1 = new ChatRequest.Userbean()
Then you can set the ID to it:
user0.setUser_id(8);
user1.setUser_id(25);
To finally add these users to the ChatRequest you need a instance of that as well:
final ChatRequest chatRequest = new ChatRequest();
Adding the users a simple call like that:
chatRequest.setUsers(Arrays.asList(user0, user1));
To be clear. These are the basic to create instances and set some values to classes/"models".
I think to answer your question we need some "preconditions". We assume that "someone" have already create some users and set it to the ChatRequest object which you receive in a "callback". To change some properties from the Userbean values can done in following way:
#Override
public void onChatRequestCreated(ChatRequest request) {
request.getUsers().get(0).setUser_id(8);
request.getUsers().get(1).setUser_id(25);
}
To set these values you should use this code:
users.get(0).setUser_id(8);
users.get(1).setUser_id(25);
I'm new(ish) to java and I'm making a program for fun that allows you to create different users, login to those users, and make notes. I'm stuck on the user creation part. There is this one line of code that won't work. I have an array called userarr that holds user objects. Inside the object is the user creation method. This is the line of code that takes the variables you type in for the username and password and plugs it into the usercreation method:
userarr[userarr.length+1] = new user.usercreation(username,password);
It says it can't find usercreation method inside the class. But I don't know how to use the usercreation method outside the object and be able to create different named objects.
Here is the entire class:
public class TextGame {
static Scanner scan = new Scanner(System.in);
class user extends TextGame {
String username;
int password;
String[] notes;
public void usercreation(String username, int password) {
this.username = username;
this.password = password;
}
public void login(int password) {
this.password = password;
System.out.println("please type the password to proceed.");
if (scan.nextLine().equals(this.password)) {
System.out.println("logged in. type 'note' to access notes, or 'logoff' to log off this user.");
}
}
}
static user[] userarr;
public static void newuser() {
System.out.println("\n\nType the username for this user.");
String username = scan.nextLine();
System.out.println("Username is now " + username + ". is this what you want? type 'yes' to proceed, or 'no' to enter username again.");
if (scan.nextLine().equals("no")) {
newuser();
}
else {
System.out.println("\n\n type the password for this user. (numbers only.)");
int password = scan.nextInt();
System.out.println("user is " + username + " and password is " + password + " is this what you want?");
if (scan.nextLine().equals("no")) {
newuser();
} else {
userarr[userarr.length + 1] = new user.usercreation(username, password);
}
}
}
public static void main(String[] args) {
System.out.println("Welcome to LINCOLN COMP console OS. Type 'new' to create a new user, type 'log' to log in to an existing user, or type 'exit' to leave.\nif you are asked a yes or no question, if you type something ether than yes or no, it will default to yes.");
String ch1 = scan.nextLine();
switch (ch1) {
case "new":
System.out.println("Initializing user creation method:");
newuser();
break;
case "log":
break;
case "exit":
System.out.println("Goodbye!");
System.exit(0);
break;
}
}
}
Okay, so starting with new user.usercreation(username,password);
usercreation is not a static inner class of user, so you can't create it
usercreation is a method of user which returns void, so you returns nothing, so you can't assign it to anything.
You could...
Create the instance of user, apply the properties and assign it to the array as separate actions
user newUser = user();
newUser.usercreation(username,password);
userarr[userarr.length+1] = newUser;
Equally, you could make usercreation a factory methhod, but I'm trying to keep it simply.
You could...
Based on what you seem to be trying to do, is make the usercreation method into a class constructor, which would make more sense...
class user extends TextGame {
String username;
int password;
String[] notes;
public user(String username, int password) {
this.username=username;
this.password=password;
}
public void login(int password) {
this.password=password;
System.out.println("please type the password to proceed.");
if (scan.nextLine().equals(this.password)) {
System.out.println("logged in. type 'note' to access notes, or 'logoff' to log off this user.");
}
}
}
Then you could just do...
userarr[userarr.length+1] = new user(username,password);
You're also haven't create an instance of the userarr, so you're going to hit a NullPointerException
You should do something like...
userarr = new user[10];
before you try and use it.
This will allow you to maintain ten instances of the user class. You should also check to ensure that you've not exceeded the number of available elements in the array before you try and add new elements.
Have a look at the Arrays Trail for more details
I'd encourage you to have a look at Code Conventions for Java, which make it easier for other people to read your code and make it easier for you to read others
Before you use the usercreation method from a different class, you must first instantiate an object of usercreation class to gain access to it's properties(methods, variables) in a different class.
Example:
UserCreation us = new UserCreation (default constructor parameters);
userarr[userarr.length+1] = us.usercreation(username,password);
You should really be using a constructor:
public user(String username, int password) { // should be named User
this.username = username;
this.password = password;
}
Then you could add a user to an array like so:
userarr[userarr.length+1] = new User("username", 1); // doesn't work!
...Except, this code will fail because you didn't instantiate the array. And even if you had, you can't assign an element to an array like this. Arrays do not automatically re-size themselves, so when you try to add an element like this you will get an ArrayIndexOutOfBoundsException and your program will exit.
Firstly, I'd like to state that you haven't instantiated the userarr array yet. So, I recommend to do that first.
Secondly,new user.usercreation(username,password); usercreation is not a static inner class of user, so you can't create it.
Thirdly, usercreation is a method which returns void in which case you can't assign it to anything.
it seems that you want to invoke this method:
public void usercreation(String username, int password) {
this.username=username;
this.password=password;
}
In order to invoke that method, you must create an object of type user first in order to invoke it.
Example:
user user1 = new user();
user1.usercreation(username,password);
userarr[userarr.length+1] = user1;
However, the easiest way would be to make a constructor to initialise the username and password like below:
public user(String username, int password) {
this.username=username;
this.password=password;
}
Hence you can easily do this:
userarr[userarr.length+1] = new user(username,password);
I have some doubts regarding how to do the following operation on a class that follow the Singleton model.
I have this original Singleton class:
public class ThreadsManager {
// I can have only one instance:
private final static ThreadsManager instance = new ThreadsManager();
// Private constructor:
private ThreadsManager() {
}
public static ThreadsManager getInstance(){
return instance;
}
}
Ok, this work well but now I have to modify it adding a new property (a String named userName) that have to be initialized when the singleton object is build and that
can not be changed at a later time
So I am trying to do something like it:
public class ThreadsManager {
private final static ThreadsManager instance = new ThreadsManager();
private final static String userName;
private ThreadsManager() {
}
public static ThreadsManager getInstance(String user){
userName = user;
return instance;
}
}
So I am trying to add the new String userName variable that is static (once for the class) and final (can not be changed at a second time)
My problem is that Eclips marks as an error the lines:
1) private final static String userName; saying to me that:
The blank final field userName may not have been initialized
It seems that would that the field will be initialized (I can initialize it to null but since it is final...I can't initialize later in the constructor)
2) userName = user; say to me that:
The final field ThreadsManager.userName cannot be assigned
So what is the best solution to handle this situation?
If I remove the final from the userName variable definition it seems to me that work well but then I can change this value but maybe I simply can not provide the setter method for this field so I prevent external changes....
Some ideas?
I think you want a singelton 'with arguments'. This should explain it :
Singleton with Arguments in Java
It is not going to be singleton if you want multiple state of an instance of that class,
you could create a cache of Object keyed with user so it would still be singleton for same state asked
private final Map<String, ThreadsManager> instanceCache = Collections.synchronizedMap<String, ThreadsManager>();
Also make sure you don't leak memory if you have tons of states for this class
Since this class is a Singleton then the name shouldn't really change too much. I would suggest just keeping it as a constant inside the class. If the name might change when the program is executed on different occasions then see Solution 2 below.
Solution 1:
public class ThreadsManager
{
private final static ThreadsManager instance = new ThreadsManager();
private String userName;
private ThreadsManager()
{
final String name = "Name";
userName = name;
}
public static synchronized ThreadsManager getInstance(String user)
{
return instance;
}
}
Solution 2:
If you really want to set the name of the Singleton and every time the program is execute the name might be different. Just add this method:
private String userName = null;
// Can only be set after Singleton is created and when userName is null.
public void setName(String n)
{
if(userName == null)
userName = n;
}
Don't make your getInstance() method have a parameter, that is a bad design. Every time someone, or you, tries to get an instance from your class they/you have to provide a parameter which will be 99% of the time be irrelevant.
You can do it using a nested class.
public class ThreadsManager {
private static String userName;
private ThreadsManager() {
}
public static ThreadsManager getInstance(String user){
if (userName == null)
userName = user;
// the holder's instance is only initialised at this point,
// after userName is set.
return Holder.instance;
}
static class Holder {
private final static ThreadsManager instance = new ThreadsManager();
}
}
First of all:
private final static String userName
may only be initialized inside the private constructor or during definition.
Secondly
You may end up with a null instance, so you might do something like this:
public class ThreadsManager {
private final static ThreadsManager instance = new ThreadsManager();
private String userName;
private ThreadsManager() {
}
private ThreadsManager(String user) {
userName = user;
}
public static ThreadsManager getInstance(String user){
if(instance == null) {
instance = new ThreadsManager(user);
} else {
Logger.getInstance().logWarning("User has already been set. Will continue with user ["+username+"].);
}
return instance;
}
}
The handling of how to deal with a second user name handed needs some thinking.
Overall you should try to keep the getInstance() method parameter free since it leads to the above mentioned problems.
How about
public class ThreadsManager {
private final static ThreadsManager instance = new ThreadsManager();
private static String userName;
public static synchronized ThreadsManager getInstance( String user ) {
if ( username == null ) { userName = user; }
return instance;
}
That would ensure userName is only set the first time.
It is, however, potentially very confusing semantics for a singleton to take a parameter that is ignored on subsequent getInstance()'s - possibly even race-condition-prone, depending on your use-case.
Cheers,