Java:Add name of each instance of object to list - java

As the tittle says i want to save each new created object of Person's name in a list:
This is my code so far
package javaapplication4;
import java.util.*;
public class Person {
private String namePerson;
static List personList = new ArrayList();
{
personList.add(getPersonName());
}
public Person(String namePerson){
this.namePerson = namePerson;
}
public void setPersonName(String namePerson){
this.namePerson = namePerson;
}
public String getPersonName(){
return namePerson;
}
public void setPersonList(List personList){
this.personList= personList;
}
public static List getPersonList(){
return personList;
}
each time i am creating a person object its gets added as a 'null' spot in the list (when i use println).
how i change that to the name of the new object Person
like
Person Guy = new Person("NameOfGuy"); then list must be [NameOfGuy].

{
personList.add(getPersonName());
}
The above is called an instance initializer. It is executed before the constructor is executed. At that time, getPersonName will return null as you haven't yet set the value of namePerson.
Move that inside the constructor
public Person(String namePerson){
this.namePerson = namePerson;
this.personList.add(namePerson);
}
Sidenote: It is a bad practice to use raw types. You are using a raw List. It must be as
List<String> personList = new ArrayList<>();
What is a raw type and why shouldn't we use it?

As pointed out by #user7, you are adding the name into the list at the wrong place. What you should be doing is, adding person's name into list while you are creating person's object, i.e. inside your constructor. Replace your constructor with this :
public Person(String namePerson){
this.namePerson = namePerson;
personList.add(namePerson);
}

You can do the job Doing below changes to the Person class:
import java.util.*;
public class Person {
private String namePerson;
static List<String> personList = new ArrayList<>();
public Person(String namePerson) {
this.namePerson = namePerson;
personList.add(this.namePerson);
}
public void setPersonName(String namePerson) {
this.namePerson = namePerson;
}
public String getPersonName() {
return namePerson;
}
public void setPersonList(List personList) {
this.personList = personList;
}
public static List getPersonList() {
return personList;
}
}

Related

How to add an element in an instanced class arraylist

I have this code to create a class User
public class User {
private String name;
private ArrayList<User> owners = new ArrayList<>();
public User(String name, ArrayList<User> owners) {
this.name = name;
this.owners = owners;
}
public String getName() {
return name;
}
public void addOwner(User owner) {
owners.add(owner);
}
If i create an instance of this class with
User jhil = new User(name, new ArrayList<>());
What do i do to add a string element to the arraylist
I've tried with the addOwner method with
jhil.addOwner(jhilsara);
but i get a the method addOwner(String) is undefined for the type User error
I've also tried with the ArrayList add method
jhil.add(jhilsara);
But that doesn't work either.
So my question is what do i need to do in order to add something to the arraylist of an instanced of my class User
You have your ArrayList set to contain objects of the User class, not Strings. Change the declaration of it to:
private ArrayList<String> owners = new ArrayList<>();
Then, you also have to change addOwner to:
public void addOwner(String owner) {
owners.add(owner);
}

How to Create Immutable Class with List<String> Element in class

Immutable Class with List
package com.text.immutable;
import java.util.Collections;
import java.util.List;
// An immutable class Student
public final class Student
{
final String name;
final int regNo;
final List<String> courses; // want to make Immutable
public Student(String name, int regNo, List<String> courses)
{
this.name = name;
this.regNo = regNo;
this.courses = Collections.unmodifiableList(courses);
}
public String getName()
{
return name;
}
public int getRegNo()
{
return regNo;
}
public List<String> getCourses() {
return courses;
}
}
Testing Immutable Class to Break Immutability
package com.text.immutable;
import java.util.ArrayList;
import java.util.List;
class ImmutablityTest
{
public static void main(String args[])
{
List<String> courses = new ArrayList<String>();
courses.add("java");
courses.add("spring");
courses.add("hibernate");
courses.add("rest");
Student s = new Student("ABC", 101, courses);
System.out.println("Before Update List");
System.out.println(s.getName());
System.out.println(s.getRegNo());
System.out.println(s.getCourses());
courses.add("Hibernate"); // Able to Change which affect final OutCome
//s.getCourses().add("SpringBoot"); // giving Exception in thread "main" java.lang.UnsupportedOperationException
System.out.println("After Update List");
System.out.println(s.getName());
System.out.println(s.getRegNo());
System.out.println(s.getCourses());
}
}
Output is
Before Update List
ABC
101
[java, spring, hibernate, rest]
After Update List
ABC
101
[java, spring, hibernate, rest, Hibernate]
why and how this new Course element added into the List as its from Client Side can be added up any time so how we can fix this issue as this immutable class should not allow to modifying after once created
this.courses = Collections.unmodifiableList(courses);
That creates, as the name says, an unmodifiable list. But that is just a view on the original list. Thus changes to that original list become visible in your "unmodifiable" view.
When in doubt: clone your list, like:
this.courses = new ArrayList<>(courses);
And then ensure that your getter does:
return Collections.unmodifiableList(courses);
Not the best in context of memory, but works:
// An immutable class Student
public final class Student
{
final String name;
final int regNo;
final List<String> courses; // want to make Immutable
public Student(String name, int regNo, List<String> courses)
{
this.name = name;
this.regNo = regNo;
this.courses = new ArrayList(courses);
}
public String getName()
{
return name;
}
public int getRegNo()
{
return regNo;
}
public List<String> getCourses() {
return new ArrayList(courses);
}
}
On input (in constructor) you create copy of list and on output (in getter) you create copy.
read about immutableLists and you'll find that an Immutable and Unmodifiable Are Not the Same.
I guess (from your question) you are expecting an unmodifiable list which you simply don't create...
see this answer for a proper solution
With Collections.unmodifiableList, it creates a wrapper around the original list and that wrapper object is unmodifiable. The original list can still be updated.
So, in order for the List<String> courses list to be immutable, you can use Apache collection common library.
List<String> immutableList =
com.google.common.collect.ImmutableList.of("Geeks", "For","Geeks");
ImmutableList has overridden the List.add method to always throw exception java.lang.UnsupportedOperationException
Second alternative is to create the list inside the constructor itself.
public Student(String name, int regNo, String... args)
{
this.name = name;
this.regNo = regNo;
courses = (List)Arrays.asList(args);
}
And call it like this :
Student s = new Student("ABC", 101, "a","a","a","a");

Using a class without creating a new instance of it

Newish to Java and very new to Android development.
I have followed the following tutorial - Android tutorial (Basic Hello World App) and I am now changing it slightly as a proof of concept.
Basically I want to use a class I have created but I am having some difficulties. The class is shown below.
public class Employee {
private HashMap<String, String> employees = new HashMap<>();
public void setEmployees(String name, String jobTitle) {
employees.put(name, jobTitle);
System.out.println(employees);
}
public String getEmployees(String name){
return employees.get(name);
}
}
I populate the HashMap from MainActivity.java. Using the set method above, this works as expected. I have tested it and I can see the HashMap has the required number of entries.
My problem is when getting the data back. How do I use the class. I have a file name DisplayMessageActivity.java and the following code within it.
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.TextView;
public class DisplayMessageActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_display_message);
// Get the Intent that started this activity and extract the string
Intent intent = getIntent();
String message = intent.getStringExtra(MainActivity.EXTRA_MESSAGE);
// Capture the layout's TextView and set the string as its text
TextView employee_name = findViewById(R.id.employee_Name);
employee_name.setText(message);
TextView employee_title = findViewById(R.id.employee_Title);
employee_title.setText(employee.getEmployees(message));
}
}
The last line is where I am getting the error. This is because it doesnt know what employee is. I presume I need to add:
Employee employee = new Employee;
If I add this within the onCreate method it creates a new instance and therefore it has new values. I have also added it just above onCreate with the same results.
What am I missing?
To retain the data you would want to make the variable and the methods static
public class Employee {
private static HashMap<String, String> employees = new HashMap<>();
public static void setEmployees(String name, String jobTitle) {
employees.put(name, jobTitle);
System.out.println(employees);
}
public static String getEmployees(String name){
return employees.get(name);
}
}
This means that only one version can exist at a time. You would call the class directly and the method.
employee_title.setText(Employee.getEmployees(message))
Replace your Employee class code with below one
public class Employee {
private static HashMap<String, String> employees;
public Employee() {
if (employees == null) {
employees = new HashMap<>();
}
}
public void setEmployees(String name, String jobTitle) {
employees.put(name, jobTitle);
System.out.println(employees);
}
public String getEmployees(String name) {
return employees.get(name);
}
}
Hope that helps you.
You can use Singleton in-memory cache to keep your employees.
public class Employee {
private static sInstance;
private HashMap<String, String> employees = new HashMap<>();
private Employee(){
// No instance available
}
public static synchronized Employee getInstance(){
if(sInstance == null){
sInstance = new Employee();
}
return sInstance;
}
public void setEmployees(String name, String jobTitle) {
employees.put(name, jobTitle);
System.out.println(employees);
}
public String getEmployees(String name){
return employees.get(name);
}
}
Later you can use your in-memory cache like the following:
Employee.getInstance().getEmployees(message);

I am trying to print the name of the list but somehow the reference from the arraylist is not working?

Customer is a class. The Class list is arraylist of Customer.
I have added the Customers to list but when I want to print all the customer names from the list I get null only.
import java.util.*;
public class Assignment1 {
public static void main(String args[])
{
List list = new List();
list.addCustomer("man");
list.addCustomer("man");
//System.out.println(list);
list.printx();
}
}
class Customer{
public String name;
public Customer(String name)
{
name = this.name;
}
}
class List
{
ArrayList<Customer> list = new ArrayList<Customer>();
public void addCustomer(String name1)
{
Customer x = new Customer(name1);
list.add(x);
System.out.println(list.get(0));
}
public void printx()
{
for(int i =0;i < list.size();i++)
{
System.out.println(list.get(i).name);
}
}
}
Inside your Customer constructor, you need to set ::
this.name = name;
and not the other way round! :P
What you have done right now is that you change the function parameter name to the class parameter name which is currently null(default initialization). So, you never initialize name variable of the Customer class, and hence you always get null when you print it.
I suggest you override the toString method in class Customer, it helps you debug your Customer objects. For example, you can change the local variable to assignedName as below:
class Customer{
public String name;
public Customer(String name)
{
this.name = name;
}
#Override
public String toString(){
return "customer name:" + this.name;
}
}
this.name and name are different things in the Customer constructor:
this.name is an instance variable and name is a local variable defined in your constructor.
// you should narrow the modifier to private, and implement getter and setter for it
public String name;
public Customer(String assignedName){
this.name = assignedName;
}

Java - get fields names of certain types

I have an example class below and I want to return all class fields of certain type, in this example of type Image.
public class Contact {
private String surname, lastname, address;
private int age, floor;
private Image contactPhoto, companyPhoto;
private boolean isEmployed;
public String[] getAllImages() {
String images[] = // missing code
return images;
// in this case, I want to return {"contactPhoto","companyPhoto"}
}
}
I need a help here. How can I find all class fields of certain type. I will be calling this method in another class ofc.
Use reflection to access the fields declared on the class. Then iterate through the fields and check to see if their type matches Image.
You could also create a more useful method by accepting two parameters a target Class and a searchType Class. The method would then searches for fields with the target of the type searchType.
I would also recommend making this method static, since it really doesn't depend on any of the classes state.
Example
public class Contact {
private String surname, lastname, address;
private int age, floor;
private Image contactPhoto, companyPhoto;
private boolean isEmployed;
public static String[] getFieldsOfType(Class<?> target, Class<?> searchType) {
Field[] fields = target.getDeclaredFields();
List<String> results = new LinkedList<String>();
for(Field f:fields){
if(f.getType().equals(searchType)){
results.add(f.getName());
}
}
return results.toArray(new String[results.size()]);
}
public static String[] getAllImages(){
return getFieldsOfType(Contact.class, Image.class);
}
public static void main(String[] args) {
String[] fieldNames = getAllImages();
for(String name:fieldNames){
System.out.println(name);
}
}
}
A simpler alternative to using reflection would be to use a map as the primary data type for the field you are interested in:
public class Contact {
private static final String CONTACT_PHOTO = "contactPhoto";
private static final String COMPANY_PHOTO = "companyPhoto";
private String surname, lastname, address;
private int age, floor;
private HashMap<String, Image> images;
private boolean isEmployed;
public Contact() {
images = new HashMap<String, Image>();
images.put(CONTACT_PHOTO, null);
images.put(COMPANY_PHOTO, null);
}
public String[] getAllImages() {
Set<String> imageNames = images.keySet();
return imageNames.toArray(new String[imageNames.size()]);
}
public void setContactPhoto(Image img) {
images.put(CONTACT_PHOTO, img);
}
public Image getContactPhoto() {
return images.get(CONTACT_PHOTO);
}
public void setCompanyPhoto(Image img) {
images.put(COMPANY_PHOTO, img);
}
public Image getCompanyPhoto() {
return images.get(COMPANY_PHOTO);
}
}
Using field names as values can cause headaches.
If you need to identify individual images with strings, you could create a HashMap.
Use your current field names as keys and Image objects as values.
https://docs.oracle.com/javase/8/docs/api/java/util/HashMap.html
You can retrieve all key values (in your case,the names) via the method keySet()
Edit: Here's a working example class, derived from yours, but only with the relevant fields:
import java.awt.Image;
import java.util.HashMap;
import java.util.Set;
public class Contact
{
private HashMap<String, Image> images;
public Contact ()
{
images = new HashMap<String, Image>();
images.put( "contactPhoto", null);
images.put( "companyPhoto", null);
}
public Set<String> getAllImages()
{
return images.keySet();
}
public static void main(String[] args)
{
System.out.println(new Contact().getAllImages());
}
}
use:
Field[] fields=this.getClass().getFields();
...
for (...){
if ( fields[i].getType() == ?? ){
...
}
}

Categories

Resources