I have a user list
List<User> usrList1 = new ArrayList<User>();
userList.add(new User("usr1",11,""));
userList.add(new User("usr2",22,""));
userList.add(new User("usr3",33,""));
another User List contains
List<User> usrList2 = new ArrayList<User>();
userList2.add(new User("",11,"add1"));
userList2.add(new User("",22,"add2"));
now how can I merge these two List and get a single list of User using id, considering performance. Consider the size of userList1 and userList2 are around 50.
List<User> usrList = new ArrayList<User>();
userList.add(new User("usr1",11,"add1"));
userList.add(new User("usr2",22,"add2"));
userList.add(new User("usr3",33,""));
This is pretty straight forward for a small list, without considering performance issues and assuming a merge strategy of appending Name and Data fields:
Copy (shallow) list1 into a new list merged
Iterate over list2
For each item in merged check if item in list2 already exists
If the item exists, just update its fields
If it does not exist, append it to the end of merged
Code:
public static List<User> Merge(List<User> list1, List<User> list2) {
List<User> merged = new ArrayList<User>(list1);
for (User user : list2) {
boolean found = false;
for (User u : merged) {
if (u.Id == user.Id) {
found = true;
u.Name += user.Name;
u.Data += user.Data;
break;
}
}
if (!found) {
merged.add(user);
}
}
return merged;
}
You can user HashMap as helper data structure
For key is needed to use user id (integer value in list)
public static void main(String[] args) {
List<User> userList1 = new ArrayList<User>();
userList1.add(new User("usr1", 11, ""));
userList1.add(new User("usr2", 22, ""));
userList1.add(new User("usr3", 33, ""));
List<User> userList2 = new ArrayList<User>();
userList2.add(new User("", 11, "add1"));
userList2.add(new User("", 22, "add2"));
// Insert all elements from first list to hash map
HashMap<Integer, User> userMap = new HashMap<>();
for (User user : userList1) {
userMap.put(user.getId(), user);
}
// Update user elements
for (User user : userList2) {
User update = userMap.get(user.getId());
update.setAddres(user.getAddress());
}
// convert hash map to list
List<User> merge = new ArrayList<>();
merge.addAll(userMap.values());
System.out.println(merge);
}
Note:
HashMap will not preserve the order of elements. If it is needed to merge list be in the same order as userList1 then use LinkedHashMap.
Related
I have this Requirement :
Construct each Doctor with their respective Appointments and return a doctorList. Input is Appointment List for whole Hospital.
What I have is the followings:
Two classes given with the following variables.
Class Appointment{
String doctorName;
DateTime startTime;
DateTime endTime;
String speciality;
//Getters-Setters
}
Another Class :
Class Doctor{
String name;
String speciality;
List <Appointment> appointments;
//Getters-Setters
}
Requirement is :
Construct each Doctor with their respective Appointments and return a doctorList.
Input is Appointment List for whole Hospital.
Can some body tell what should be my approach?
I hope this will help you. Use Map to maintain the appointments of each doctor. In the below code you can get the appointment details using the doctor's name.
`//appointments - input list
Map<String, List<Appointment>> map = new HashMap<>();
for(Appointment app : appointments) {
if(!map.containsKey(app.getDoctorName())) {
List<Appointment> li = new ArrayList<>();
li.add(app);
map.put(app.getDoctorName(),li);
} else {
map.get(app.getDoctorName()).add(app);
}
}`
You can use HashMap.
HashMap<Doctor, ArrayList> doctorList = new HashMap<>();
Might not be a good idea in your case mainly because I do not understand what you are trying to achieve.
If you need match doctors with Appointment by both Speciality and Name, then:
Map<String, List<Appointment>> map = appointmentList
.stream()
.collect(Collectors.groupingBy(e -> e.getDoctorName() + e.getSpeciality()));
List<Doctor> doctors = new ArrayList<>();
for (String doctorNameAndSpeciality : map.keySet()) {
List<Appointment> appointments = map.get(doctorNameAndSpeciality);
if (!appointments.isEmpty()) {
Doctor doctor = new Doctor();
Appointment appointment = appointments.get(0);
doctor.setName(appointment.getDoctorName());
doctor.setSpeciality(appointment.getSpeciality());
doctor.addAllAppointments(appointments);
}
}
return doctors;
if you need use only 'name', then just remove 'speciality'
if(Collections.frequency(ItemSet, distinctItemsList) >= support) {
ItemList.addAll(ItemSet);
FrequentItem1.put(ItemList, Collections.frequency(ItemSet, distinctItemsList));
System.out.println(FrequentItem1);
}
the above code is just repeating the transaction instead of giving item followed by frequency
ItemList is the array list of individual transactions
TID. ItemList
Tylenol,Thermometer
water,Milk,Battery
ItemSet is an array list with elements like Tylenol, Thermometer,
Battery etc..i.e the Main function looks like this
try {
Statement statement= connection.createStatement();
String sql="Select distinct TID from transaction";
ResultSet SetTid= statement.executeQuery(sql);
while(SetTid.next()) {
int initialTID= SetTid.getInt("TID");
TID.add(initialTID);
}
System.out.println("TID Items");
for(int initialTID : TID) {
String sqlitem="Select ItemSet from transaction where TID="+ initialTID;
ResultSet setItem= statement.executeQuery(sqlitem);
while(setItem.next()) {
String items= setItem.getString("ItemSet");
//System.out.println("&&&&&&&&"+ items);
ItemList.add(items);
ItemSet=Arrays.asList(items.split(","));
noOfTransaction++;
System.out.println(initialTID+":"+ items);
//System.out.println(initialTID+":"+ ItemList);
}
for(String items : ItemSet) {
System.out.println("&&&&>>"+ items);
if(! distinctItemsList.contains(items)) {
distinctItemsList.add(items);
}
}
System.out.println("No of transaction"+ noOfTransaction);
}
}
DistinctItem list is an array list that contains unique items.
If you are using java-8, below should generate hashmap with word and it's frequency-
Map<String, Long> collect = wordsList.stream().collect(groupingBy(Function.identity(), counting()));
I want to convert my Resultset to List of object . This is my query:
String querystring1= "SELECT userID, privilege"
+ "FROM dbo.User order by userID, privilege";
userID privilege
------------------
1001 read
1001 write
1001 execute
1001 delete
1006 execute
1006 read
1006 write
1007 read
1007 write
I have a class User defined like :
public class User {
private int userID;
private List<String> userPrivelege;
}
I want to have as an output to a list of Users, and this is my implemented code:
String previousId = null;
List<String> PrivList= new ArrayList<String>();
List<User> allUserList= new ArrayList<User>();
while(result_set.next()) {
String userID = result_set.getString("userID");
String privilege = result_set.getString("privilege");
if (previousId == null) { // first time
User user = new User();
PrivList.add(privilege);
previousId=userID;
} else if (previousId.equals(userID) {
PrivList.add(privilege);
} else {
user.setUserPrivilege(PrivList);
allUserList.add(user);
PrivList.clear();
previousId=null;
}
}
The problem is, other than the first user object created, all the next one are always missing the first value which means user 1006 will have 2 privileges other than 3.
Any idea?
All User objects refer the same object List of privileges as you don't create a new instance for each User. Instead you clear only the List.
Consequently, all Users are set with 2 privileges as the last User that you handle has 2 privileges.
So replace :
PrivList.clear();
by :
PrivList = new ArrayList<>();
That's because You Miss the First privilege of the New User here,
else {
user.setUserPrivilege(PrivList);
allUserList.add(user);
PrivList.clear();
previousId=null;
}
Do the privilege initialization for the next user here.
PrivList = new ArrayList<>();
PrivList.add(privilege);
As far as I can see, you are never assigning the user ID to the User object?
PrivList.clear(); clears the list that you have just assigned to a user. Instead create a new list, as davidxxx also said.
As anchreg said, after you have created a user and added it to the list, you need to initialize the next user in the same way as you did the first time.
After your loop terminates, if previousId is not null (that is, any user previlege was processed at all), you need to assign values to the last user and add it to the list in the same way as in the last else case in the loop.
All of this said a more elegant solution could be coded using streams.
You need to create a new instance of PrivList for each user.
Additionnaly, you need to add a privilege for the next user, otherwise you lose that information on the loop.
Edits shown by the <-- comments.
while(result_set.next()) {
String userID = result_set.getString("userID");
String privilege = result_set.getString("privilege");
if (previousId == null) { // first time
User user = new User();
PrivList.add(privilege);
previousId=userID;
} else if (previousId.equals(userID) {
PrivList.add(privilege);
} else {
// nex user
user.setUserPrivilege(PrivList);
allUserList.add(user);
PrivList = new ArrayList<>(); // <--
PrivList.add(privilege); // <--
previousId=null;
}
}
In m y opinion, I think that is not a good model. You should have a second table with privileges related with an user. But to solve your question:
List<String> privList= new ArrayList<String>();
Map<Integer, List<String>> hmUserPrivileges = HashMap<Integer, String>();
while(result_set.next()) {
int userID = result_set.getInt("userID");
String privilege = result_set.getString("privilege");
if (!hmUserPrivileges.contains(userID)) {
privList= new ArrayList<String>();
}
privList.add(privilege);
hmUserPrivileges.put(userID, privList);
}
List<User> allUserList = new ArrayList<User>();
Iterator<Entry<Integer, List<String>>> iterator = hmUserPrivileges.entrySet().iterator();
while(iterator.hasNext()) {
Entry<Integer, List<String>> entry = iterator.next();
User user = new User()
user.setUserID(entry.getKey());
user.setUserPrivelege(entry.getValue());
allUserList.add(user);
}
I have some data in SQLite database, which I would like to show in a List based on small logic.
I have three fields in my table,
first field : id
second field : title
third field : type
where Type can be : Monthly or Yearly
Here is my code:
// Generate real data for each item
public List<ReminderItem> generateData(int count) {
ArrayList<ReminderItem> items = new ArrayList<>();
// Get all reminders from the database
List<Reminder> reminders = rb.getAllReminders();
// Initialize lists
List<String> Titles = new ArrayList<>();
List<String> Type = new ArrayList<>();
List<Integer> IDList= new ArrayList<>();
// Add details of all reminders in their respective lists
for (Reminder r : reminders) {
Titles.add(r.getTitle());
Type.add(r.getType());
IDList.add(r.getID());
}
return items;
}
This is the situation, where I need help from you guys, As you can see still, I am showing each and every record from database to list, no matter from which Type it belongs.
Now, I just want to show records in a List, which belongs to Type "Monthly" only
So exactly what I have to do ? How can I show records in a List for the Type of "Monthly" only
I have a String variable namely, strType = "Monthly";
You have two option to do this.
First is directly get only those record from database which reminder type is "Monthly" by execute below sql statement.
SELECT id,title,type FROM table_name WHERE type = "Monthly"
Second is check reminder type is equal to "Monthly" when you add data into List.
for (Reminder r : reminders) {
String reminderType = r.getType();
if(reminderType.equalsIgnoreCase(strType)) {
Titles.add(r.getTitle());
Type.add(reminderType);
IDList.add(r.getID());
}
}
Full Code
// Generate real data for each item
public List<ReminderItem> generateData(int count) {
String strType = "Monthly";
ArrayList<ReminderItem> items = new ArrayList<>();
// Get all reminders from the database
List<Reminder> reminders = rb.getAllReminders();
// Initialize lists
List<String> Titles = new ArrayList<>();
List<String> Type = new ArrayList<>();
List<Integer> IDList= new ArrayList<>();
// Add details of all reminders which type="Monthly" in their respective lists
for (Reminder r : reminders) {
String reminderType = r.getType();
if(reminderType.equalsIgnoreCase(strType)) {
Titles.add(r.getTitle());
Type.add(reminderType);
IDList.add(r.getID());
}
}
return items;
}
When you select from your sqlite db you can add filter there
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_A + " WHERE " +
COLUMN_TYPE + "=?", new String[]{ arg0 }); // arg0 = "Monthly"
This will increase your performance instead of filtering List after load
If we have input file which contains the pair of state and city, there can be multiple cities which belongs to same state. What we have to do is we have to make that single state as key and the cities which belongs to that state as value.
For example, I am reading the following data from a file:
Maharashtra - Pune
Madhyapradesh - Bhopal
Maharashtra - Mumbai
Maharashtra - Nagpur
Here Maharashtra will become a key, with Pune, Mumbai and Nagpur becoming values. What I did is first I split The data into state and city. I am now trying to store the states in a list and then check the list but I am stuck.
How can I make the Maharashtra as key and Pune, Mumbai and Nagpur as its respective values? Like this:
Maharashtra- Pune, Mumbai, Nagpur.
This is what I have so far:
public class DataManagerImpl implements DataManager {
#Override
public Map<String, List<String>> populateCityDataMap(String fileName)
throws FileNotFoundException {
// TODO Auto-generated method stub
Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> valSetOne = new ArrayList<String>();
List<String> list=null;
String nameAndRollNumber=null;
String[] nameAndRollNumbers =null;
String State=null;
Scanner s = null;
try {
s = new Scanner(new File("F:\\Participant_Workspace\\Q4\\CityStateLocator\\StateCityDetails.txt"));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
while (s.hasNext()) {
nameAndRollNumber = s.nextLine();
nameAndRollNumbers = nameAndRollNumber.split("-");
State = nameAndRollNumbers[0];
String City=nameAndRollNumbers[1];
/*System.out.println(valSetOne);
map.put(State,valSetOne);*/
System.out.println(State+" "+City);
list.add(State);
}
/*Iterator<String> CrunchifyIterator = list.iterator();
while (CrunchifyIterator.hasNext()) {
System.out.println(CrunchifyIterator.next());
}*/
System.out.println(list);
return null;
}
}
You need something like map with key as state (which is a String) and value as list of cities (i.e. list of strings). So your data structure should be something like:
Map<String, List<String>> map ...
List<String> cities = map.get(state);
if (cities == null) {
cities = new ArrayList<String>();
map.put(state, cities);
}
cities.add(city);