I am having some trouble with this. I want to add the member variables to a map.
Here is my code:
Sprinter.java
public class Sprinter {
private int age;
private String name;
private String address;
public Sprinter() {
}
public Sprinter(int age, String name, String address) {
this.age = age;
this.name = name;
this.address = address;
}
public void setAge(int age) {
return this.age = age;
}
public int getAge() {
return this.age;
}
public void setName(String name) {
return this.age = age;
}
public String getName() {
return this.name;
}
public void setAddress(String address) {
return this.address = address;
}
public String getAddress() {
return this.address;
}
Worker.java
Sprinter _s = new Sprinter();
_s.setAge(16);
_s.setName("Chris");
_s.setAddress("123 Street");
Map.java
public class Maper {
private Sprinter _sp = new Sprinter();
private static Map<String, Sprinter> map = new HashMap<String, Sprinter>();
public void printMap() {
map.put(_sp.getName(), _sp);
System.out.println(map);
I want the String in the map to be the key, and the values to be the age, address, and name fields from the Sprinter class. In my Worker.java class I use:
Maper _m = new Maper();
_m.printMap();
And my output is: {"Chris", "Chris"};
However, I want all of the variables to be added. Any advice?
A map relates a single key with a single value - it explicitly can't relate a single key ("Chris") with three different values (16, "Chris", "123 Street"). You have two obvious choices:
Use three different keys (e.g. "Chris_age" -> 16, "Chris_name" -> "Chris", "Chris_address" -> "123 Street"). This option is further complicated because the values are of different types (int vs String) so you'd need to declare your map as Map<String, Object> which is generally not great. The insert code would look something like:
map.put(_sp.getName() + "_name", _sp.getName());
map.put(_sp.getName() + "_age", _sp.getAge());
map.put(_sp.getName() + "_address", _sp.getAddress());
The better option is to use a container object to hold the three values, and store that in the map. That's what the code you already have does. In that case, if you want the age you need to do something like:
map.get("Chris").getAge();
Related
We have two Pojo files.
Person {
String name;
int age;
String address;
String phoneNo;
boolean isMarried;
}
and
OtherPerson {
//mandatory fields are name and age
String name_other;
int age_other;
//other fields
Map<String, Object> otherFields;
}
and a json file which defines the mapping between the fields using name
mappingJson {
"name":"name_other",
"age":"age_other",
"address":"address_other",
"phoneNo":"phoneno_other",
"isMarried":"ismarried_other"
}
Please let me know the best approach to convert Person to OtherPerson. So that the mandatory fields map to name_other and age_other while the other fields should be added to the map(otherFields)
It may be
Person->Person(json)->OtherPerson
Or Person->OtherPerson.
EDIT:
"Use case: We have an API which used to accepts a POJO 'A' but now it needs to accept POJO 'B' as an input argument. This POJO needs to get converted into POJO 'A' which can then be used for persisting into the database. Also POJO 'B' is not under our control"
That's a perfect fit for Jackson Converter! :)
It could work like this:
class OtherPerson {
#JsonProperty("name")
public String name_other;
#JsonProperty("age")
public int age_other;
Map<String, Object> otherFields = new LinkedHashMap<>();;
#JsonAnySetter
public void add(String key, Object value) {
otherFields.put(key, value);
}
}
// ...
Person person = new Person();
person.name = "Avinash";
person.age = 25;
person.address = "Mumbai";
person.phoneNo = "910731";
person.isMarried = true; // :( sorry ladies!
// ...
ObjectMapper mapper = new ObjectMapper();
// If we cannot put #JsonAutoDetect on top of Person.class,
// we need to add handling of non-public fields
// since Person seems to neither have public fields nor setters
mapper.configOverride(Person.class)
.setVisibility(JsonAutoDetect.Value.defaultVisibility()
.withFieldVisibility(JsonAutoDetect.Visibility.NON_PRIVATE));
OtherPerson other = mapper.convertValue(person, OtherPerson.class);
VoilĂ !
I personally would do this without JSON. It's my understanding that some fields in the Map are optional while name and age are mandatory. In the case of the optional content, I would use the Ternary operator to create the person object. This allows you to add some default value if the optional field is not available.
Main
import java.util.HashMap;
import java.util.Map;
/**
*
* #author blj0011
*/
public class JavaApplication30 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Map<String, Object> map1 = new HashMap();
map1.put("address", "123 Hello Street");
map1.put("phoneNo", "555-555-5555");
map1.put("isMarried", true);
OtherPerson otherPerson = new OtherPerson("John Doe", 22, map1);
Map<String, Object> map2 = new HashMap();
map2.put("address", "4456 Bye Road");
map2.put("isMarried", false);
OtherPerson otherPerson2 = new OtherPerson("Jane Doe", 21, map2);
Person person1 = new Person(otherPerson.getName_other(), otherPerson.getAge_other(),
otherPerson.getOtherFields().containsKey("address") ? otherPerson.getOtherFields().get("address").toString(): "",
otherPerson.getOtherFields().containsKey("phoneNo") ? otherPerson.getOtherFields().get("phoneNo").toString(): "",
otherPerson.getOtherFields().containsKey("isMarried") ? Boolean.valueOf(otherPerson.getOtherFields().get("isMarried").toString()): false);
System.out.println(person1);
Person person2 = new Person(otherPerson2.getName_other(), otherPerson2.getAge_other(),
otherPerson2.getOtherFields().containsKey("address") ? otherPerson2.getOtherFields().get("address").toString(): "",
otherPerson2.getOtherFields().containsKey("phoneNo") ? otherPerson2.getOtherFields().get("phoneNo").toString(): "",
otherPerson2.getOtherFields().containsKey("isMarried") ? Boolean.valueOf(otherPerson2.getOtherFields().get("isMarried").toString()): false);
System.out.println(person2);
}
}
Person
/**
*
* #author blj0011
*/
public class Person {
private String name;
private int age;
private String address;
private String phoneNo;
private boolean isMarried;
public Person(String name, int age, String address, String phoneNo, boolean isMarried) {
this.name = name;
this.age = age;
this.address = address;
this.phoneNo = phoneNo;
this.isMarried = isMarried;
}
public boolean isIsMarried() {
return isMarried;
}
public void setIsMarried(boolean isMarried) {
this.isMarried = isMarried;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhoneNo() {
return phoneNo;
}
public void setPhoneNo(String phoneNo) {
this.phoneNo = phoneNo;
}
#Override
public String toString() {
return "Person{" + "name=" + name + ", age=" + age + ", address=" + address + ", phoneNo=" + phoneNo + ", isMarried=" + isMarried + '}';
}
}
OtherPerson
/**
*
* #author blj0011
*/
public class OtherPerson {
//mandatory fields are name and age
private String name_other;
private int age_other;
//other fields
private Map<String, Object> otherFields;
public OtherPerson(String name_other, int age_other, Map<String, Object> otherFields) {
this.name_other = name_other;
this.age_other = age_other;
this.otherFields = otherFields;
}
public Map<String, Object> getOtherFields() {
return otherFields;
}
public void setOtherFields(Map<String, Object> otherFields) {
this.otherFields = otherFields;
}
public String getName_other() {
return name_other;
}
public void setName_other(String name_other) {
this.name_other = name_other;
}
public int getAge_other() {
return age_other;
}
public void setAge_other(int age_other) {
this.age_other = age_other;
}
}
Output
Person{name=John Doe, age=22, address=123 Hello Street, phoneNo=555-555-5555, isMarried=true}
Person{name=Jane Doe, age=21, address=4456 Bye Road, phoneNo=, isMarried=false}
As you can see in the output OtherPerson2 did not have a phone number. Empty string was use as the default value.
I am trying to write a program which stores information about a person in a linked list. I made a simple person class to store the name, age and addresses in the list. I would also like to store multiple addresses for EACH person, and a fact about the place in another linked list, inside the person class.
So for example, "Tara" can have a home address of "10 Central Ave" and a work address of "5 Willow street" etc. The problem is, I don't know how to have a linked list inside another.
My goal is to check whether the person's name is already on the list, and if so, add another address for them. (So that there is no repeats). I am a beginner and can really use some help.
public class Person {
private String name;
private int age;
public LinkedList <String> adresses;
public Person() {
name = "default";
age = 0;
adresses = new LinkedList<>();
}
public Person(String n, int a) {
name = n;
age = a;
}
public LinkedList<Adress> getAdresses() {
return adresses;
}
public void setAdresses(LinkedList<Adress> adresses) {
this.adresses = adresses;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return name+" "+age+" "+adresses;
}
}
public class Adress {
public String adress;
public String fact;
public Adress(String a, String f) {
adress = a;
fact = f;
}
public String getAdress() {
return adress;
}
public void setAdress(String adress) {
this.adress = adress;
}
public String getFact() {
return fact;
}
public void setFact(String fact) {
this.fact = fact;
}
}
public class Test {
public static void main(String[] args) {
Person Tara = new Person("Tara",35);
Person Judah = new Person("Judah",28);
Person Mark = new Person("Mark",45);
Person Seth = new Person("Seth",23);
LinkedList<Object> tester = new LinkedList<>();
tester.add(Tara);
tester.add(Judah);
tester.addLast(Mark);
tester.addLast(Seth);
System.out.println(tester);
}
}
How is about to use the next classic data structure for your project?
public class Person {
private String name
private int age;
public List<Address> addresses;
//...
}
Here is my code of UserDetail class.
public class UserDetail {
public void user_detail() {
Members m1=new Members("Rashid Faheem","0312-6193172","House No. 430, Street No. 5 Mehmood Abad Pindora, Rawalpindi");
Members m2=new Members("Yawar Hayat","0312-6193172", "RajanPur");
Members m3=new Members("Azhar Malik", "0312-6193172", "RajanPur");
Members m4=new Members("Muhammad Ali", "0312-6193172", "RajanPur");
Members m5=new Members("Muhammad Nazik", "0312-6193172", "RajanPur");
ArrayList<Members> al = new ArrayList<Members>();
al.add(m1);
al.add(m2);
al.add(m3);
al.add(m4);
al.add(m5);
System.out.println("These are our Members.");
For (Members m:al) {
System.out.println(m.getName());
}
}
}
Here is code from Members Class which I am using as DataType in ArrayList.
public class Members {
private String name, phone,address;
public Members(String name, String phone, String address) {
name=name;
phone=phone;
address=address;
}
public String getName() {
return name;
}
public String getPhone() {
return phone;
}
public String getAddress() {
return address;
}
}
Update
I changed my code according to your advice but another problem now. I am only getting name but not phone and address.
Output
These are our Members.
Rashid Faheem
Yawar Hayat
Azhar Malik
Muhammad Ali
Muhammad Nazik
for (Members m:al) {
System.out.println(m.getName());
}
Notice the lowercase f. Just a typo.
EDIT:
Your constructor is also just assigning the constructor arguments to themselves. You need to assign the constructor arguments to the class variables.
public Members(String name, String phone, String address) {
this.name = name;
this.phone = phone;
this.address = address;
}
You should replace For by for.
And update Members with additionnal this :
public Members(String name, String phone, String address)
{
this.name=name;
this.phone=phone;
this.address=address;
}
There are two syntax errors. Once you correct them you should be able to print the members list:
for not For.
for (Members m : al) {
System.out.println(m.getName());
}
Members constructor. The code is not assigning the parameters to the member variables.
public Members(String name, String phone, String address) {
this.name=name;
this.phone=phone;
this.address=address;
}
Refer https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
First of all, you should stick to the Java naming conventions - so your method user_detail should be named userDetail. You might want to consider naming it print as that's what it is supposed to do.
Next, the constructor in your Members class does nothing, since you miss the this. as prefix of the left side of your operation. So you would want to write it like this (as mentioned by WatchdogReset):
public Members(String name, String phone, String address) {
this.name = name;
this.phone = phone;
this.address = address;
}
Another problem is the typo in For which is supposed to be for (stated by ninnemank).
I refactored your code, to show you a possible way of doing what you want - of course this is rather opinionated and not a perfect solution.
Members
public class Members {
private String name;
private String phone;
private String address;
public Members(String name, String phone, String address) {
this.name = name;
this.phone = phone;
this.address = address;
}
public String getName() {
return name;
}
public String getPhone() {
return phone;
}
public String getAddress() {
return address;
}
#Override
public String toString(){
return String.join(" / ", this.getName(), this.getPhone(), this.getAddress());
}
}
UserDetail
import java.util.ArrayList;
import java.util.List;
public class UserDetail {
private List<Members> members;
public UserDetail() {
this.members = new ArrayList<>();
}
public boolean addMember(Members member){
return this.members.add(member);
}
#Override
public String toString(){
return this.members.stream()
.map(member -> member.toString())
.reduce((a, b) -> String.join(System.lineSeparator(), a, b))
.orElse("");
}
}
Main
public class Main {
public static void main(String[] args) {
Members m1 = new Members("Rashid Faheem", "0312-6193172", "House No. 430, Street No. 5 Mehmood Abad Pindora, Rawalpindi");
Members m2 = new Members("Yawar Hayat", "0312-6193172", "RajanPur");
Members m3 = new Members("Azhar Malik", "0312-6193172", "RajanPur");
Members m4 = new Members("Muhammad Ali", "0312-6193172", "RajanPur");
Members m5 = new Members("Muhammad Nazik", "0312-6193172", "RajanPur");
UserDetail userDetail = new UserDetail();
userDetail.addMember(m1);
userDetail.addMember(m2);
userDetail.addMember(m3);
userDetail.addMember(m4);
userDetail.addMember(m5);
System.out.println("These are our Members.");
System.out.println(userDetail);
}
}
Output
These are our Members.
Rashid Faheem / 0312-6193172 / House No. 430, Street No. 5 Mehmood Abad Pindora, Rawalpindi
Yawar Hayat / 0312-6193172 / RajanPur
Azhar Malik / 0312-6193172 / RajanPur
Muhammad Ali / 0312-6193172 / RajanPur
Muhammad Nazik / 0312-6193172 / RajanPur
I'm trying to understand how to use the Java 8 Streams API.
For example, I have these two classes:
public class User {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
public class UserWithAge {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
private int age;
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
I have a List<User> of ten users, and I want to convert this to a List<UserWithAge> of ten users with the same names and with a constant age (say, 27). How can I do that using the Java 8 Streams API (without loops, and without modifying the above classes)?
You could use the map() feature of the stream to convert each User instance in your list to a UserWithAge instance.
List<User> userList = ... // your list
List<UserWithAge> usersWithAgeList = userList.stream()
.map(user -> {
// create UserWithAge instance and copy user name
UserWithAge userWithAge = new UserWithAge();
userWithAge.setName(user.getName());
userWithAge.setAge(27);
return userWithAge;
})
.collect(Collectors.toList()); // return the UserWithAge's as a list
While you could do this, You should not do like this.
List<UserWithAge> userWithAgeList = new ArrayList<UserWithAge>();
userList.stream().forEach(user -> {
UserWithAge userWithAge = new UserWithAge();
userWithAge.setName(user.getName());
userWithAge.setAge(27);
userWithAgeList.add(userWithAge);
});
public class ListIteratorExp {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
Person p1 = new Person();
p1.setName("foo");
Person p2 = new Person();
p2.setName("bee");
list.add(p1);
list.add(p2);
list.stream().forEach(p -> {
String name = p.getName();
System.out.println(name);
});
}
}
class Person{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
output:-
vishal
thakur
I have a couple to class in which I'm getting and setting a few things and then finally calling it in my main method. But when I call my class in the main method it just gives me the object instead of name,address and age. I know this structure is very complicated but I want to keep this structure because later on I will be adding a lot of things to this. It would be AMAZING if someone could tell me how to do this. I would really appreciate this. Below is my code for all my classes
This is my first class
public class methodOne
{
public String getName()
{
String name = "UserOne";
return name;
}
public int getAge()
{
int age = 17;
return age;
}
public String getAddress()
{
String address = "United States";
return address;
}
}
This is my second class
public class methodTwo
{
String name;
String address;
int age;
public methodTwo(methodOne objectOne)
{
name=objectOne.getName();
address=objectOne.getAddress();
age=objectOne.getAge();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
This is my third class
public class methodThree {
private methodTwo methodTwoInMethodThree;
private methodOne methodOneInMethodThree;
public methodThree()
{
this.methodOneInMethodThree = new methodOne();
this.methodTwoInMethodThree = new methodTwo(methodOneInMethodThree);
}
public methodTwo getMethodTwoInMethodThree() {
return methodTwoInMethodThree;
}
public void setMethodTwoInMethodThree(methodTwo methodTwoInMethodThree) {
this.methodTwoInMethodThree = methodTwoInMethodThree;
}
}
This is my fourth class which is the method maker
public class methodMaker {
public methodThree brandNewFunction(methodTwo object)
{
methodThree thirdMethod = new methodThree();
thirdMethod.setMethodTwoInMethodThree(object);
return thirdMethod;
}
}
This is my main class which calls methodMaker. What I want to achieve is that when I print the value it should print the name,address and age but instead it just prints trial.methodThree#4de5ed7b
public class mainClass {
public static void main(String args[])
{
methodMaker makerOfMethods = new methodMaker();
methodOne one = new methodOne();
methodTwo object = new methodTwo(one);
System.out.println(makerOfMethods.brandNewFunction(object).toString());
}
}
What you need to do is to override the default implementation of the .toString() method in the objects you want to print out:
#Override
public String toString()
{
return "Name: " + this.name;
}
EDIT:
I do not know exactly where you are printing, and you naming convention doesn't really help out, but from what I am understanding, you would need to implement it in all of you classes since they all seem to be related to each other.
So, in your methodOne class (can also be applied to methodTwo):
#Override
public String toString()
{
return "Name: " + this.name + " Age: " + this.age + " Address: + " this.address;
}
In your methodThree class:
private methodTwo methodTwoInMethodThree;
private methodOne methodOneInMethodThree;
#Override
public String toString()
{
StringBulder sb = new StringBuilder();
if(this.methodTwoInMethodThree != null)
{
sb.append("Method 2:").append(methodTwoInMethodThree.toString());
}
if(methodOneInMethodThree != null)
{
sb.append("Method 1:").append(methodOneInMethodThree.toString());
}
return sb.toString();
}
When you call
MyClass myObject = new MyClass();
System.out.println(myObject);
Implicitly , java calls instead
System.out.println(myObject.toString());
So, if in MyClass, you override toString(), then whatever your toString method returns is what's gonna be printed.
Side note: are you confusing classes and methods? Methods are functions in your classes, classes are wrappers around a bunch of attributes and methods. Your naming is confusing.
try this code:
public class methodTwo
{
String name;
String address;
int age;
public methodTwo(methodOne objectOne)
{
name=objectOne.getName();
address=objectOne.getAddress();
age=objectOne.getAge();
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString(){
return name+" "+address+" "+age;
}
}
Are you printing the object using println()?
From the docs, println():
calls at first String.valueOf(x) to get the printed object's string value
This string value is obtained from the object's toString() method, which:
returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object
So if you want to print anything other than this you have to override the toString() method in your object and return a string containing whatever you want.
Just google "override tostring java" and you will see a ton of examples.