I have a list of Order objects -
class Order {
Date date;
float amount;
String companyCode;
}
List<Order> orders = /* Initialize with list of order objects with valid data */
I have a list of Company objects -
class Company {
String name;
String code;
String address;
}
List<Company> companies = /* Initialize with list of company objects with valid data */
I need a to create a map of companyCode and name.
Is there some library that would allow me to write code like this (where BeanSearch is the hypothetical library class)?
Map<String, String> codeAndName = new HashMap<String, String>();
for(Order o: orders) {
codeAndName.put(o.getCompanyCode(),
BeanSearch.find(companies, "code", o.getCompanyCode).getName());
}
Alternatively is there another good way to do it?
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/CollectionUtils.html should work for you right? Specifically you can use the find method
Related
I currently have three object classes, Transaction, User and Group.. Transaction collects: id, who paid, date, description, amount and an ArrayList of involved users IDs. This works perfectly but adds many lines of code through methods of iterating through users to find which user is who. My question is, could I have an ArrayList *partecipants = new ArrayList; which has the reference of all users ?
class Transaction{
private static AtomicInteger count = new AtomicInteger(0);
private int id = count.incrementAndGet();
private String paid;
private Date date;
private String message;
private Double amount;
private ArrayList<Integer> users = new ArrayList<Integer>();
A short example:
Let's say you have a simple User class:
public class User {
private int id;
private String name;
// etc
}
And let's say you originally have a List of these:
List<User> users;
Finding a user by id can be done like this:
users.stream().filter(u -> u.getId() == id).findFirst();
However, if the users list is large, that can be slow.
You could store the users in a Map:
Map<Integer, User> usersById;
This map would only refer to the other objects, so takes up little space (but still takes up some, it's like an index).
You can fill this map like this:
usersById = users.stream().collect(Collectors.toMap(User::getId, Function.identity()));
Or more traditionally:
usersById = new HashMap<>();
for(User u : users) {
usersById.put(u.getId(), u);
}
To find a user by id now, you can use this (with O(1) performance):
User user = usersById.get(id);
I'm retreiving the list of product bought by the user but I'm getting an error since in the constructer product is of type List. I didn't knew how to convert it
String buyer = request.getParameter("buyer");
List prodlist = request.getParameter("product");
Bill bill = new Bill(buyer, prodlist);
here is the code of the constructeur
public Bill(String buyer, List<Product> product) {
super();
this.buyer = buyer;
this.product= product;
}
the attribute of the class Product
private int id;
private String name;
private float price;
(Edited: using an object class.)
Either
String[] products = request.getParameterValues("product");
List<Product> prodlist = new ArrayList<>();
for (String productName : products) {
Product product = loadProduct(productName); // Or such
prodlist.add(product);
}
or use
List<String> prodlist = Arrays.asList(request.getParameterValues("product"));
That getParameterValues is for multiple values for the same parameter "product" is possible. This is in general a String[]. The getParameter(String) method is for a parameter occurring only once; in fact a special case.
The same result would be for an URL "http: ... my.html?product=pc&product=phone&product=tablet".
You should check that indeed the HTML contains several <input name="product">, maybe using the browser developer tools, generally evoked by F12 inside the browser.
We know that since Java 7, Switch's expression can be a String. So I was making an app, where, when a user selects a category he/she will be assigned the concerned department as per the category value. Here's the code:-
public class Selector {
///String array to save the departments
private final static String[] DEPTS = {
"A",
"B",
"C",
"D"
};
//String array for the categories
private final static String[] CATEGORY = {
"Wind",
"Air",
"Fire",
"Cloud",
"River",
"Tree",
"Abc",
"Def"
};
//return the department when user selects a particular category item from above
public static String setDepartment(String category) {
switch(category){
case "Wind":
return DEPTS[0];
case "Air":
return DEPTS[1];
case "Fire": case "Cloud": case "River":
return DEPTS[2];
case "Tree": case "Abc": case "Def":
return DEPTS[3];
}
return null;
}
}
So I was thinking just how I can return the department item using the array index of department, can I use the same thing in the case value, like,
case CATEGORY[0]: case CATEGORY[1]:
return DEPTS[2];
Cause if the category items contain a large string than the cases will become too long to write. If java doesn't allow this, can you suggest some other way so that my code doesn't become cumbersome? Thanks.
Why don't you use a enum to do that.
public class Selector {
private enum DepartmentCategory = {
Wind("A"),
Air("B"),
Fire("C"),
Cloud("C"),
River("C"),
Tree("D"),
Abc("D"),
Def("E");
private String department;
DepartmentCategory(String department) {
this.department = department;
}
public String getDepartment() {
return department;
}
};
}
Now if you are given a department, you can easily get the category by the following code.
String category = "Wind";
DepartmentCategory dc = DepartmentCategory.valueOf(category);
dc.getDepartment(); // Returns the department
You could use a Map<String, String> to map the category to the department.
Then instead of a switch, you'll have to use map.get(category) which will return the department.
You could make it a Map<String, List<String>> to map the department to the categories, and do
for(String dept : map.keySet())
{
if(map.get(dept).contains(category))
{
return dept;
}
}
Edit: With enums, that works well if there will be no extra departments or categories in the future. A map allows a more dynamic approach. Both work well, if used correctly
I would use a Map<String, String> to store your associations between department and category rather than a switch statements. It seems like you are trying to use an Array[] for a purpose in which it wasn't intended.
If you use a Map<String, String> then you can store your data as follows:
Map<String, String> departments = new HashMap<String, String>();
departments.add("Wind", "A")
departments.add("Fire", "B")
departments.add("Fire", "C")
departments.add("River", "C")
departments.add("Cloud", "C")
You can then easily retrieve departments names by using the syntax:
String category = "Cloud"
String department = departments.get(category)
If you want to associate multiple departments you can use Map<String, List<String>> to represent a relationship between a type and category and multiple departments.
Traditionally if you think about representing this in a database you would be using a map with an index and an object underneath.
I don't think you want to use Arrays to do this in your case.
I have two different objects list like those:
public class Person {
private int id;
private String name;
private String surname;
}
public class Name {
private int id;
private String name;
}
My Person list doesn't have the field name filled. I need to merge it with the Name list matching the field id.
Question: How is the best way to do this with Java 8 streams?
First, using a Map is better for accessing the Name objects, so using streams here is a solution:
List<Person> personList = ...
List<Name> nameList = ...
Map<Integer,String> nameMap = nameList.stream()
.collect(Collectors.toMap(Name::getId,Name::getName));
personList.forEach(person -> person.setName(nameMap.getOrDefault(person.getId(), "")));
You can do it like this:
Map<Integer, String> map = names.stream().collect(Collectors.toMap(o -> o.id, o -> o.name));
for (Person person : persons) {
person.name = map.getOrDefault(person.id, "");
}
Assuming names is your list of Names and persons is your list of Person, also if the person id is not found the default name is the empty string.
I'm trying to find a way to join two List of objects with two unique attributes to produce a new List of Object.
Users Class
public class Users {
String id;
String name;
String gender;
}
Adding some data here
List<Users> userList=new ArrayList<Users>();
userList.add(new Users("1","AA","Male"));
userList.add(new Users("2","BB","Male"));
userList.add(new Users("3","CC","Female"));
Academics Class
public class Academics {
String id;
String name;
String grade;
String professional;
}
Adding some data here
List<Academics> academicsList=new ArrayList<Academics>();
academicsList.add(new Academics("1","AA","A","Doctor"));
academicsList.add(new Academics("2","BB","B","Carpenter"));
academicsList.add(new Academics("3","CC","C","Engineer"));
My Profile
Public class Profile {
String id;
String name;
String gender;
String grade;
String professional;
}
Here I need to calculate the List by Outer joining the UserList and academicsList with the 2 common attributes of id and name
I do need to do this as a bulk operation instead of going with any For/While loops one by one.
Is there is any way to use Stream to achieve this?
Update 1:
The Joining here would be like Outer-Joining where some id would not be present in academics but it would be present in Users.
In such case We need to show empty values for the grade/professional in Profile List(s)
Thanks in advance,Jay
It would make sense to convert one of the input Lists to a Map, in order to quickly correlate between entries of the first and second Lists.
Map<String,Users> userByID = userList.stream().collect(Collectors.toMap(Users::getID,Function.identity));
Now you can Stream over the elements of the second List:
List<Profile> profiles =
academicsList.stream()
.map(a -> {
Profile p = null;
Users u = userByID.get(a.getID());
if (u != null) {
p = new Profile();
// now set all the Profile fields based on the properties
// of the Users instance (u) and the Academics instance (a)
}
return p;
})
.filter(Objects::nonNull)
.collect(Collectors.toList());
Given your additional requirement, you should create a Map for the second List and Stream the first List:
Map<String,Academics> academicsByID = userList.stream().collect(Collectors.toMap(Academics::getID,Function.identity));
List<Profile> profiles =
userList.stream()
.map(u -> {
Profile p = new Profile ();
Academics a = academicsByID.get(u.getID());
// now set all the Profile fields based on the properties
// of the Users instance (u) and the Academics instance (a)
// (if available)
return p;
})
.collect(Collectors.toList());