proper container / data-structre in Java - java

I am writing a test for an address form. Therefore I need valid data.
My first approach is a method that returns a HashMap<String, String> with this data. (i.e. m.put("city, "New York")).
I am not sure if this is a proper data-structure in my case. I need just a container that holds the data so the data can be returned within a method. The number and the names of attributes are fixed, so they won't change while running. So I don't really need the functionality of adding and removing elements to the map dynamically.
Because of that I consider implementing a class called AddressData or something like that. And by creating AddressData-Objects the needed data could be assigned to the class attributes. So I can either make them public or fetch them via a getter method.
What do you think? Other data-structures suggestions?
They way I implemented it so far:
public HashMap getValidData(String country){
HashMap<String, String> data = new HashMap<String, String>();
if(country.equals("USA")){
data.put("firstname","John");
data.put("lastname","Green");
data.put("city","New York");
}
else if(country.equals("Germany")){
//add valid german address data
}
return data;
}
Implementation draft with a class:
class AddressData{
private String firstname;
private String lastname;
private String city;
public AddressData(String country){
if(country.equals("USA")){
firstname="John";
lastname="Green";
city="New York";
}
else if(country.equals("Germany")){
//add valid german address data
}
}
public String getFirstname(){ return firstname; }
// other getters
}

If you have a fixed list of attributes, you should create a class that represents your form like the AddressData you suggest.

To make your code more flexible, you should not have String country in your AddressData, otherwise, you will end up with many if-else conditions to handle many countries, rather store the countrycode as a key and AddressData as value object in the HashMap as shown below:
AddressData class:
public class AddressData {
private String firstname;
private String lastname;
private String city;
public AddressData(String firstname, String lastname, String city){
this.firstname=firstname;
this.lastname=lastname;
this.city=city;
}
public String getFirstname(){ return firstname; }
// other getters
}
Usage of AddressData:
HashMap<String, AddressData> data = new HashMap<String, AddressData>();
AddressData addressData1 = new AddressData("John", "Green", "New York");
data.put("USA", addressData1);
//You can add other address data

Related

java map values from an object

I am new to collections and looking for help. I am trying to search a map using a key, and return the values of the key which is from another object. This is my code so far.
public class Employer {
Map<String, NewHire> employee = new HashMap<>();
}
public void addEmployee(String fullName, String age, String location, String JobTitle) {
NewHire newEmployee = new NewHire(age, location, JobTitle);
this.employee.put(fullName, newEmployee);
}
The code for the other object is -
public class NewHire {
private String age;
private String location;
private String jobTitle;
}
public NewHire(String aAge, String aLocation, String aJobTitle) {
this.age = aAge;
this.location = aLocation;
this.jobTitle = aJobTitle;
}
I then create like so -
Employer CompanyA = new Employer();
CompanyA.addEmployee("JohnSmith", "23", "London", "Service Desk");
I wanted to create a method that can search the map for a key specified by the user, in this case "JohnSmith", and if found, it then shows me the age, location and jobTitle of that person but I really am not sure how I would go about this.
The best way to go about it in my opinion is the way Titulum said, using Optional.
I would just leave another way, a bit not so nice, but you may understand it better.
You can Override the toString() method in the NewHire class and use it, or create getters for the properties:
#Override
public String toString(){
return String.format("Age: %s\nLocation: %s\nJobTitle: %s", age, location, jobTitle);
}
// getters
public String getJobTitle() {
return jobTitle;
}
public String getLocation() {
return location;
}
public String getAge() {
return age;
}
On your Employer class, if you want to use the not so much nicer way of doing it (although i recommend using Optional):
public NewHire getEmployeeByName(String fullName){
return employee.get(fullName);
}
Then to use it:
Employer employer = new Employer();
employer.addEmployee("JohnSmith", "23", "London", "Service Desk");
NewHire newHire = employer.getEmployeeByName("sJohnSmith");
if(newHire != null) {
System.out.println(newHire.toString());
// using getters
System.out.println(newHire.getAge());
System.out.println(newHire.getJobTitle());
System.out.println(newHire.getLocation());
}
You can simply write the method as follows:
public Optional<NewHire> findByFullName(String fullName) {
return Optional.ofNullable(employee.get(fullName));
}
This will return you an Optional, which is an Object in Java that contains either something or nothing. To see if the Optional contains anything you can do:
Optional<NewHire> possiblyFoundNewHire = findByFullName("SomeName");
possibleFoundNewHire.ifPresent(newHire -> {
System.out.println(newHire); // Or formatted as you would like.
});

About ArrayList in future use?

I am a java beginner and learning the oop concept. I already success to store the object value into a arraylist and i try to display the arraylist in the main method. But the problem is if i remove the add value code in the main method and display again the arraylist. The arraylist will show the null value which is []. Please help me and is this is my understanding problem or need to store in txtfile? database or what to get the or store the arraylist and can use for display all the record, update or delete that i add before
This is for my practice project and unuse the database to create a POS system based on oop concept. I had learn php and c# before and i do the same type project and not very confused because of using database. But now i feel confused how to use the java to create it and can has ability to create member, update member profile and etc based on oop concept. Please help me or give the suggestion. Very thank you.
my super class
class Person {
private List<Customer> customers;
private String name;
private String gender;
private String email;
public Person(){
}
public Person(List<Customer> customers){
this.customers = customers;
}
public Person(String name, String gender, String email){
***
}
public List<Customer> getCustomers(){
return customers;
}
public void addCustomer(Customer customer){
customers.add(customer);
}
//Getter
***
//Setter}
my subclass
class Customer extends Person{
private int custID;
private static int customerID = 10001;
public Customer(String name, String gender, String email,int custID){
super(name, gender, email);
this.custID = custID;
customerID++;
}
public int getCustID(){
return custID;
}
public static int getCustomerID(){
return Customer.customerID;
}
public String toString(){
return String.format("%d%30s%7s%30s\n", getCustID(), getName(), getGender(),getEmail());
}
}
My main method
public class POS {
public static void main(String[] args) {
Customer p1 = new
Customer("Halo","M","haloworld#gmail.com",Customer.getCustomerID());
Customer p2 = new
Customer("Haloo","F","halobitchworld#gmail.com",Customer.getCustomerID());
List<Customer> cList = new ArrayList<>();
cList.add(p1); //if remove
cList.add(p2); // if remove
Person customer = new Person(cList);
System.out.print(customer.getCustomers());
}
}
i expect if write the code in main like
{ Person person = new Person();
System.out.print(person);
}
will display the result that i add before
If you don't want to add the customers to an ArrayList in your main-function a good way to do it would be to set the List<Customer> static in your Person-class and adding the customers as they get created.
public class Person {
private static List<Person> customers = new ArrayList<>();
public static List<Person> getCustomers() {
return customers;
}
private String name;
private String gender;
private String email;
public Person(String name, String gender, String email) {
this.name = name;
this.gender = gender;
this.email = email;
customers.add(this);
}
/* getters */
}
now in your main()-function you only have to create the Customers and they automatically get added to the customers list and therefore you can then get them by calling the static function getCustomers()
public static void main(String[] args) {
Customer p1 = new Customer("Halo","M","haloworld#gmail.com",Customer.getCustomerID());
Customer p2 = new Customer("Haloo","F","halobitchworld#gmail.com",Customer.getCustomerID());
System.out.print(Customer.getCustomers());
}
To store them you would have to implement some kind of storage system like MySQL or simply a text file if you don't really have to access them from everywhere. You will find plenty of tutorials here on Stackoverflow in how to do that.
EDIT
#andy-turner pointed out that doing customers.add(this); inside a constructor really is a pain. So you could just create the ArrayList<Customer> in your Main-class and then work like this:
private static ArrayList<Customer> customers = new ArrayList<>();
public static void main(String[] args) {
customers.add(new Customer("Halo","M","haloworld#gmail.com",Customer.getCustomerID()));
customers.add(new Customer("Haloo","F","halobitchworld#gmail.com",Customer.getCustomerID()));
System.out.print(customers);
}
Variables in memory are ephemeral
An ArrayList, like all of the Java Collections Framework, is a structure for holding data in memory. When your program ends its execution, all of that memory is freed. Your ArrayList is destroyed.
Storage
If you want to share data between runs, you must store it.
You can open a file in storage and write data values as text. On next run, read that file, parse the text back into objects, and populate a new ArrayList.
You can open a file and have your ArrayList write itself to storage using Java Serialization technology. Or you can do the serialization yourself with another serialization format.
Or send your data values to a database, which in turn writes them to storage. On next run, retrieve from database.
Or pass your data over the network to some service which accepts the data on your behalf. On next run, ask the service for your data.
All of this is too broad to discuss on Stack Overflow. You need to do your own research and learning.
Empty array versus NULL
The arraylist will show the null value which is [].
The string [] represents an empty array, an array holding no elements. Such array is not null! Null means no array at all.
Imagine a bookshelf holding books. That’s like an array holding elements. Remove the books. The empty shelf is like an empty array, with no elements. Now take down the bookshelf and burn it. That’s a null array, meaning no array at all.

ContactEntry( ) in ContactEntry cannot be applied

I am trying to make an association list for names and emails under a contact list for class. But I don't know what is wrong with my code or really, more accurately, what it is missing?
The directions are:
"One particularly common data structure is association lists. The standard example of an association list is a dictionary. A dictionary associates definitions with words. Given an word, you can use the dictionary to look up its definition. We ca think of the dictionary as being a list of pairs of the form (w,d), where w is a word and d is its definition. A general association list is a list of pairs (k,v), where k is some "key" value, and v is a value associated to that key. In general, we want to assume that no two pairs in the list have the same key. The basic operation on association lists is : Given a key, k, find the value v associated with k, if any.
Association list are very widely used in computer science. For example, a compiler has to keep track of the location in memory associated with each variable. It can do this with an association list in which each key is an variable name and the associated value is the address of that variable in memory. Another example would be a contact list, if we think of it as associating an email address to each name on the list. The items in the list could be objects belonging to the class:
The data for a contacts list consists of a ArrayList of ContactEntry and an integer variable to keep track of how many entries are actually stored in the list. A contact list could be an object belonging too the class:
Note that the search method, getEmail, returns the value that it finds associated with the key, name. This is often done with association lists.
The program could use a lot of improvement.
Modify ContactEntry adding setters, getters, a default constructor, and a constructor whose input is a name and email.
Modify ContactList to use the above and add its own setters, getters and a default constructor.
A contact list is pretty useless unless the data in the list can be saved permanently -- that is, in a file. Add the following methods to the contact list program, such that it keeps its list of names and email addresses in a file.
Thank you to anyone who helps me in advance. I am not the brightest star.
Some sample and starting code was provided but I am sure the issue is past that. I have tried googling the question but everything is different to the point that I am not sure exactly what my problem is.
public class ContactEntry {
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
private String name;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
private String email;
}
import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.util.*;
public class ContactList {
private ArrayList<ContactEntry> list=new ArrayList<ContactEntry>();
private int entries=0;
public void addEntry(String name,String email){
ContactEntry entry=new ContactEntry(name, email);
list.add(entry);
entries++;
}
public String getEmail(String name){
for(ContactEntry entry:list){
if(entry.getName().equals(name)){
return entry.getEmail();
}
}
return null;
}
public static ContactList LoadContacts(String filepath){
File file=new File(filepath);
try (Scanner scan=new Scanner( file )){
ContactList contactList=new ContactList()
while(scan.hasNext()){
String line=scan.nextLine();
int pos=line.indexOf(':');
String name=line.substring(0,pos);
String email=line.substring(pos+1);
contactList.addEntry(name,email);
}
return contactList;
}
catch (FileNotFoundException e){
e.printStackTrace();
return null;
}
}
public void storeContacts(String filepath){
File file=new File(filepath);
try(PrintWriter pwt=new PrintWriter(file)){
for(ContactEntry entry:list){
pwt.println(entry.getName()+":"+entry.getEmail());
}
}
catch(FileNotFoundException e){
e.printStackTrace();
}
}
public static void main(String[] args) {
ContactList contactList=new ContactList();
ContactList.addEntry( name:"tim",email:"tim#gmail.com");
ContactList.storeContacts(filepath:"contacts.txt");
}
}
You need what is called a constructor. Oracle says
A class contains constructors that are invoked to create objects from the class blueprint.
The constructor allows you to make an object which holds data. By default, all classes have a "default constructor" which is just empty and looks like
public ContactEntry() {
}
You need a constructor which takes in String name and String email. This would look something like
public ContactEntry(String name, String email) {
this.name = name;
this.email = email;
}
You haven't defined a constructor for your class, which means it has the implicit no-argument constructor only (new ContactEntry()). If you want a constructor that takes name and email, you must define it.
There should be a parameterized constructor in ContactEntry class.
public ContactEntry(String name,String email){
this.name=name;
this.email=email;
}

How to modify a field in each element of list in java 8 using stream

I have the following classes:
class Employee
{
private String name;
private List<Address> addresses;
//...
//Getters and setters for all fields
}
public class Address
{
private String city;
private Timestamp startDate;
private Timestamp endDate;
private String typeOfResidence;
private String businessCode;
private String businessType;
//...
//Getters and setters for all the fields
}
Now I have an employee object which has list of addresses. Based on businessCode, I need to populate businessType.
The businessCode is already populated.
I have a function
public String public getBusinessType(String businessCode){
...
business logic...
return businessType;
}
Now please help to update businessType field in each address element.
I am trying using
List<Address> l = employee.getAddress();
IntStream.range(0, l.size).forEach();
But not sure how to call getBusinessType for each address element and update the field in each address element.
You could do it in place without the need to stream:
yourList.forEach(x -> {
x.setBusinessType(YourClass.getBusinessType(x.getBusinessCode()))
})
The classic way using a for-each loop would be :
for(Address a : employee.getAddress()){
a.setBusinessType(getBusinessType(a.getBusinessCode()));
}
Using Streams it would be :
employee.getAddress().stream().forEach(a-> a.setBusinessType(getBusinessType(a.getBusinessCode())));
But (a good IDE would tell you that) the stream() is superfluous here; List.forEach() is sufficient:
employee.getAddress().forEach(a-> a.setBusinessType(getBusinessType(a.getBusinessCode())));
Refer below line.
employee.getAddresses().forEach(employee-> employee.setCity("My City"))
Should be like this
employee.getAddress().stream().map(address->address.setBusinessType(getBusinessType(address.getBusinessCode())))
.collect(Colletors.toList());
also you can use replaceAll method.
To readability create UnaryOperator<T> and then use this function in replaceAll method.
UnaryOperator<Address> updateBusinessType = address -> {
address.setBusinessType(...);
return address;
};
employee.getAddress().replaceAll(updateBusinessType);
It can also be improved by defining a method in the Address class that update businessType property.

Basic Object Oriented Programming

I am currently studying Java and have been asked to write a program that deals with
actors and films as classes.
The actor class has the following attributes:
Name, Address, age, myFilm (an array or arraylist to hold all the films a particular actor
has starred in.
The film class has these attributes:
Name, Code (String, String)
I have implemented these classes with getter and setter methods to handle the data:
My actor class so far:
public class actor {
private String name;
private String address;
private int age;
int[] myFilms = new int[3];
public actor (String name, String address, int age) {
}
public void setName (String name) {
this.name = name;
}
public void setAddress (String address) {
this.address = address;
}
public void setAge (int age) {
this.age = age;
}
public void setFilm () {
}
public String getName () {
return name;
}
public String getAddress () {
return address;
}
}
My film class:
public class film {
private String name;
private String code;
//Constructor
public film () {
}
public void setName (String name) {
this.name = name;
}
public String getName (){
return name;
}
public String getCode (String name) {
//Get code:
//Split Function
String[] words = name.split("\\s+");
String code = "";
for (int i=0; i < words.length; i++) {
code = code + words[i].charAt(0);
code = code.toUpperCase();
}
return code;
}
}
I'm hitting a brick wall with how to approach making the program dynamic to display each actors total films. This is for a college assingnment and I am also required to do a deep copy of the array at some point. I am almost completely new to OO so this is proving a tricky task for me.
Any words of advice or a point in the right direction would be hugely appreciated.
Two comments about your classes...
Why not declare the films of an actor like this:
private List<Film> myFilms = new ArrayList<Film>();
This way, you will be able to add and remove film object references dinamically from your actor objects. You can implement getter and setter for the list and manipulate it from outside, for example. Lists (or Collections in general) are much easier to manipulate than primitive arrays.
Consider declaring classes with first capital letter, it's a convention. For example: Actor, Film.
Consider extracting a "actor that play in film" to another class, to decouple film out of actor (actor can also do theathre spectacles, vioce dubbig etc, not specialy movies.)
class ActorRole {
private Actor actor;
private Movie movie;
private int dollarsSallary;
private int scenesPlayed;
// etc.
}
If you don't want to, I'm almost sure that better create dependency from Movie to Actor than from Actor to Movie, because Movies almost surely have actos:
class Movie {
private List<Actor> actors = new ArrayList<Actor>();
}
This makes harder to count actor statistics (you have to iterate over all Movies) but I think this is a better design.
To count single actor shows:
for ( Movie movie : listOfAllMovies ) {
if ( movie.getActors().contains( myActor ) ) { // read about equals() in Java !
timesPlayed++;
}
}
If you want to make a ranking for more actors, you can use Map<Actor,Integer> to map actors to they times played counters.
This can be a lengthy operation, so you can think about cashing the results (like in above map) - the solution can be map, ActorStatistics class, simple timesPlayed field in actor etc. etc.
Don't be afraid to objects
Don't do a hard workaround to mape films to id (like your id, which is propably connected to your film code String, wich add another type-incompatibility issue.
Try to use more object references instead of workarounds, and List instead of array.
Generally, read about Collections in Java, like ArrayList and HashMap and also overriding equals() and hashCode(), and in general OOP Single responsibility principle and Class cohesion
You can compose a auto-increment container inside class actor, like vector ArrayList and so on. Or you could implement a dynamic array by yourself.
If u have a database which has a table with username and film(ID) & etc, u can create a class as follow,
Class Film{
private String actorName;
private String filmCode;
private String filmName;
....getter & setter methods
...
}
then u can create a method to get data list of Film class.
Eg:
List<Film> filmList = new ArrayList<Film>();
String actorName = "Arnold";
filmList = dbCon.getFilmListByActor(actorName);
your getFilmListByActor method should be like this,
public List<Film> getFilmListByActor(String actorName){
List<Film> filmList = new ArrayList<Film>();
//Query for get film list by actor
//assigne filmList to result set
enter code here
return filmList;
}

Categories

Resources