问题
public class Dashboard {
int REQUEST_ID, PRICE, PROCESSED;
String LOGIN_USER;
public int getREQUEST_ID() {
return REQUEST_ID;
}
public void setREQUEST_ID(int rEQUEST_ID) {
REQUEST_ID = rEQUEST_ID;
}
//all getters and setters
public class DBConnection {
public ArrayList<Dashboard> getStoreResult() {
ArrayList<Dashboard> dashRec;
try{
Class.forName("");
Connection con=DriverManager.getConnection("");
Statement st=con.createStatement();
ResultSet rs=st.executeQuery("");
HashMap<Object, List<Dashboard>> map = new HashMap<>();
while (rs.next()) {
Integer id = rs.getInt(1);
if (!map.containsKey(id)) {
dashRec= new ArrayList<Dashboard>();
map.put(id, dashRec);
}
Dashboard dash = new Dashboard();
dash.setREQUEST_ID(id);
dash.setLOGIN_USER(rs.getString(2));
dash.setPRICE(rs.getInt(3));
dash.setPROCESSED(rs.getInt(4));
map.get(id).add(dash);
}
}
}
}
I want to add name and status as user defined object in above hashmap. The name must be like A for first 3 set, B for next 2 set of rows.The status I want to insert must be lowest number in the set of rows of same ID. That is with ID 123, we need status as 1 to be inserted as object in hashmap and for id 456 we need status 2. How would it be done?
回答1:
You can loop over the map after the while-loop like this
check if list size 3, 2, or 1
Base on the your post query there are 3, 2 and 1 rows and I want to
status from 1 to 3 when rows are 3 status from 2 to 3 when rows are 2 status 1 when 1 row
based on this I write a condition to check:
list of size: 3 -> (3-3) +1 = 2
list of size: 2 -> (3-2) +1 = 2
list of size: 1 -> (3-1) +1 = 3
AtomicInteger
Because I loop over the Dashboard list
using Stream
in Foreach
and if you
want to access any variables outside this method mark as final.
So I added the Object of AtomicInteger
more information Atomic Integer Oracle
// create another map contains the lowest status for each id
Map<Integer, Integer> lowestStatus = new HashMap<>();
for (Integer key : map.keySet()) {
// get the size of the list related to that id
int size = map.get(key).size();
int status = (3 - size) + 1;
final AtomicInteger statusCounter = new AtomicInteger(status);
if (status != 3) {
map.get(key).forEach(dashboard -> {
if (!lowestStatus.containsKey(key))
lowestStatus.put(key, statusCounter.get());
dashboard.setStatus(statusCounter.getAndIncrement());
});
} else {
Dashboard dashboard = map.get(key).get(0);
dashboard.setStatus(1);
lowestStatus.put(key, 1);
}
}
, another version
CurrentStatus
To keep tracking what's the last status when having to that id
LowestStatus
Save the first occurrence to a given set of rows with a given id will take 1 value
Map<Integer, List<Dashboard>> map = new HashMap<>();
Map<Integer, Integer> lowestStatus = new HashMap<>();
Map<Integer, Integer> currentStatus = new HashMap<>();
while (rs.next()) {
Integer id = rs.getInt(1);
if (!map.containsKey(id)) {
map.put(id, new ArrayList<Dashboard>());
currentStatus.put(id, 0);
lowestStatus.put(id, 1);
}
Dashboard dash = new Dashboard();
dash.setRequestId(id);
dash.setLoginUser(rs.getString(2));
dash.setPrice(rs.getInt(3));
dash.setProcessed(rs.getInt(4));
dash.setStatus(currentStatus.get(id) + 1);
currentStatus.put(id, currentStatus.get(id) + 1); // update the status for the next iteration
map.get(id).add(dash);
}
回答2:
If I understood your requirement clearly, you want to sort the Map
in the ascending order of the requestId
and then sort the list of Dashboard
records with the same requestId
in ascending order of status
. If so, given below is the solution for the same:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
class Dashboard {
private int requestId, price, processed;
String loginUser;
public Dashboard(int requestId, String loginUser, int price, int processed) {
this.requestId = requestId;
this.price = price;
this.processed = processed;
this.loginUser = loginUser;
}
public int getRequestId() {
return requestId;
}
public int getPrice() {
return price;
}
public int getProcessed() {
return processed;
}
public String getLoginUser() {
return loginUser;
}
@Override
public String toString() {
return requestId + "\t" + price + "\t" + processed + "\t" + loginUser;
}
}
public class Main {
public static void main(String[] args) {
Map<Object, List<Dashboard>> map = new TreeMap<>();
List<Dashboard> list;
list = new ArrayList<Dashboard>();
list.add(new Dashboard(456, "B", 25, 2));
list.add(new Dashboard(456, "B", 20, 3));
map.put(456, list);
list = new ArrayList<Dashboard>();
list.add(new Dashboard(123, "A", 10, 2));
list.add(new Dashboard(123, "A", 15, 3));
list.add(new Dashboard(123, "A", 5, 1));
map.put(123, list);
list = new ArrayList<Dashboard>();
list.add(new Dashboard(789, "C", 30, 1));
map.put(789, list);
// Sort the list of Dashboard records with the same requestId in ascending order
// of status
for (Entry<Object, List<Dashboard>> entry : map.entrySet()) {
Collections.sort(entry.getValue(), Comparator.comparing(Dashboard::getProcessed));
}
// Display Result
System.out.println("reqid\tname\tprice\tstatus");
for (List<Dashboard> recordList : map.values()) {
for (Dashboard record : recordList) {
System.out.println(record.getRequestId() + "\t" + record.getLoginUser() + "\t" + record.getPrice()
+ "\t" + record.getProcessed());
}
}
}
}
Output:
reqid name price status
123 A 5 1
123 A 10 2
123 A 15 3
456 B 25 2
456 B 20 3
789 C 30 1
Notes:
- I have used TreeMap which is sorted according to the natural ordering of its keys. Since the keys are
int requestId
, we don't need to do anything to compare them. TheTreeSet
will automatically take care of keeping them in ascending order. - To sort the list of
Dashboard
records with the samerequestId
in ascending order ofstatus
, I have got the list ofDashboard
records using therequestId
as the key and then sorted theList
usingComparator.comparing(Dashboard::getProcessed)
.
来源:https://stackoverflow.com/questions/61585028/get-attributes-value-from-sql-database-as-user-defined-object-in-hashmap