I have a lot of JSON files in the following format. I want to map one attribute named Timings to integer.
test.json
"Rating": {
"ratingValue": "4.636365",
"bestRating": "5",
"worstRating": "1",
"ratingCount": "66"
},
"Timings": {
"cookTime": "PT1H",
"prepTime": "PT10M",
"totalTime": "PT1H10M"
}
I want to store the output in another JSON file after mapping. Let say, totalTime in Timings is 1H10M then we assign this as "totalTime:7". If its, "30M" we can assign this as "totalTime:3". I want to do this using java.
Required output
"Rating":
{
"ratingValue": "4.636365",
},
"Timings":
{
"totalTime": "7"
}
I tried this :
class Timings {
private String cookTime;
private String prepTime;
private String totalTime;
public String getCookTime() {
return cookTime;
}
public void setCookTime(String cookTime) {
this.cookTime = cookTime;
}
public String getPrepTime() {
return prepTime;
}
public void setPrepTime(String prepTime) {
this.prepTime = prepTime;
}
public String getTotalTime() {
return totalTime;
}
public void setTotalTime(String totalTime) {
this.totalTime = totalTime;
}
#Override
public String toString() {
return "Timings [cookTime=" + cookTime + ", prepTime=" + prepTime + ", totalTime=" + totalTime + "]";
}
}
public class Test {
public static void main(String[] args) throws IOException {
ObjectMapper mapper = new ObjectMapper();
Timings obj = mapper.readValue(new File("C:\\Users\\Anish\\Desktop\\abc.json"), Timings.class);
String totalTime = obj.getTotalTime().split("PT")[1];
int total = 0;
if (totalTime != null && !totalTime.isEmpty()) {
total = returnTotalTime(totalTime);
}
ObjectNode mainNode = mapper.createObjectNode();
ObjectNode timingNode = mapper.createObjectNode();
childNode.put("totalTime", (total > 9) ? (total / 10) : total);
mainNode.set("Timings", timingNode);
String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(mainNode);
System.out.println(json);
}
private static int returnTotalTime(String totalTime) {
if (totalTime != null && !totalTime.isEmpty()) {
String[] timeValues = totalTime.split("H");
if (timeValues.length == 0) {
return 0;
} else if (timeValues.length < 2) {
if (timeValues[0].contains("M")) {
return (timeValues[0].split("M").length <= 0) ? 0
: timeValues[0].split("M")[0].isEmpty() ? 0 : Integer.parseInt(timeValues[0].split("M")[0]);
}
return timeValues[0].isEmpty() ? 0 : Integer.parseInt(timeValues[0]) * 60;
}
int hour = timeValues[0].isEmpty() ? 0 : Integer.parseInt(timeValues[0]) * 60;
int mins = (timeValues[1].split("M").length <= 0) ? 0
: timeValues[1].split("M")[0].isEmpty() ? 0 : Integer.parseInt(timeValues[1].split("M")[0]);
return (hour + mins);
}
return 0;
}
abc.json
{
"cookTime": "PT1H",
"prepTime": "PT10M",
"totalTime": "PT1H10M"
}
Output :
{
"Timings" : {
"totalTime" : "7"
}
}
When "totalTime": "PT30M", then :
Output :
{
"Timings" : {
"totalTime" : "3"
}
}
When "totalTime": "PT23M", then :
Output :
{
"Timings" : {
"totalTime" : "2"
}
}
You can use any library to parse Json data depending of your goals.
for example org.json is a good choice and here is an example:
JSONObject object = new JSONObject(stringData);
String time = object.getJSONObject("Timings").getString("cookTime");
this way you can parse every Json data and do your business after that.
Also you can use mapping your data to a class with gson or other tools.
Related
I want to make a configuration to store items, however, when I was making the paths to get the values, something wrong happened.
HashMap<String, Text> sections;
private void loadKeys() {
List<String> list = new ArrayList<>();
for (String s : sections.keySet()) {
Text te = sections.get(s);
String changeable = s.substring(0, s.length() - 1);
for (int i = 0; i < te.lines(); i++) {
String line = te.getLine(i);
while (line.startsWith(" ")) {
line = line.substring(2);
}
if (!line.startsWith("-")) {
if (line.endsWith(":")) {
changeable = changeable + "." + line.substring(0, line.length() - 1);
} else {
list.add(changeable + "." + line);
}
}
}
}
for (String s : list) {
System.out.println(s);
}
}
Text.java
public class Text {
private List<String> lines = new ArrayList<>();
public Text(String txt) {
if (txt.contains("\n")) {
for (String s : txt.split("\n")) {
lines.add(s);
}
} else {
lines.add(txt);
}
}
public int lines() {
return lines.size();
}
public String getLine(int line) {
return lines.get(line);
}
#Override
public String toString() {
String string = "";
for (String s : lines) {
if (string.equals("")) {
string = s;
} else {
string = string + "\n" + s;
}
}
return string;
}
}
File:
Test11:
Test12:
Test13: 'test'
Test14: 'test2'
Test15: teste
Test16:
Test17: "test test"
The output I want:
Test11.Test12.Test13: 'test'
Test11.Test12.Test14: 'test2'
Test11.Test15: teste
Test11.Test16.Test17: "test test"
What I got with the code above:
Test11.Test12.Test13: 'test'
Test11.Test12.Test14: 'test2'
Test11.Test12.Test15: teste
Test11.Test12.Test16.Test17: "test test"
Test12 is being repeated. Can you help me have what I want? Thanks in advance
It is pretty easy. All you need is just keep current level depth and level name. You can do it via recursion or using queue.
public static Map<String, String> readProperties(Path path) throws IOException {
final class Level {
private final String name;
private final int offs;
public Level(String name, int offs) {
this.name = name;
this.offs = offs;
}
}
Map<String, String> map = new LinkedHashMap<>();
// contains all root items for current one with it's offset, to detecl that current level is sub level or parent
Deque<Level> levels = new LinkedList<>();
Pattern pattern = Pattern.compile("(?<offs>\\s*)(?<key>[^:]+)\\s*:\\s*(?<value>.*)\\s*");
Files.lines(path)
.map(pattern::matcher)
.filter(Matcher::matches)
.forEach(matcher -> {
int offs = matcher.group("offs").length();
// remove parent levels until reach the parent of current level
while (!levels.isEmpty() && levels.peekLast().offs >= offs) {
levels.removeLast();
}
String key = matcher.group("key");
String value = matcher.group("value");
if (value.isEmpty())
levels.add(new Level(key, offs));
else
map.put(levels.stream().map(level -> level.name).collect(Collectors.joining(".")) + '.' + key, value);
});
return map;
}
How to put inner JSONArray data into vector? The program only crash when i want to put data into the vector when I just print the data everythink works fine. Why? How to fix this?
When I run the program with vector:
0
Budapest
Szolnok
time: 0 2018.10.21. 11:20 2018.10.21. 13:25
Exception in thread "main" java.lang.NullPointerException
at Routes.addTime(Routes.java:20)
at JSONReader.main(JSONReader.java:30)
And when I run whitout vecor (just print to the console the good output):
0
Budapest
Szolnok
time: 0 2018.10.21. 11:20 2018.10.21. 13:25
time: 1 2018.10.21. 13:20 2018.10.21. 15:25
1
Veszprem
Budapest
time: 0 2018.10.30. 09:35 2018.10.30. 11:02
2
Veszprem
Gyor
time: 0 2018.11.10. 15:46 2018.11.10. 16:50
1
Gyor
Szombathely
time: 0 2018.11.05. 13:10 2018.11.05. 14:50
JSONReader.java
import org.json.JSONArray;
import org.json.JSONObject;
public class JSONReader {
static String JSON_STRING = "{\"routes\": [{\"id\": 0,\"from\": \"Budapest\",\"to\": \"Szolnok\",\"times\": [{ \"id\": 0, \"start\": \"2018.10.21. 11:20\", \"arrive\": \"2018.10.21. 13:25\" },{ \"id\": 1, \"start\": \"2018.10.21. 13:20\", \"arrive\": \"2018.10.21. 15:25\" }]}, {\"id\": 1,\"from\": \"Veszprem\",\"to\": \"Budapest\",\"times\": [{ \"id\": 0, \"start\": \"2018.10.30. 09:35\", \"arrive\": \"2018.10.30. 11:02\" }]}, {\"id\": 2,\"from\": \"Veszprem\",\"to\": \"Gyor\",\"times\": [{ \"id\": 0, \"start\": \"2018.11.10. 15:46\", \"arrive\": \"2018.11.10. 16:50\" }],}, {\"id\": 1,\"from\": \"Gyor\",\"to\": \"Szombathely\",\"times\": [{ \"id\": 0, \"start\": \"2018.11.05. 13:10\", \"arrive\": \"2018.11.05. 14:50\" }],}]}";
public static void main(String[] args) {
//RoutSystem routsystem = new RoutSystem();
JSONObject object = new JSONObject(JSON_STRING);
JSONArray routes = object.getJSONArray("routes");
for (int y = 0; y < routes.length(); y++) {
JSONObject route = routes.getJSONObject(y);
int id = route.getInt("id");
String from = route.getString("from");
String to = route.getString("to");
JSONArray time = route.getJSONArray("times");
System.out.println(id);
System.out.println(from);
System.out.println(to);
Routes rout = new Routes(id, from, to);
for (int z = 0; z < time.length(); z++) {
JSONObject valami = time.getJSONObject(z);
int id1 = valami.getInt("id");
String start = valami.getString("start");
String arrive = valami.getString("arrive");
System.out.println("time: " + id1 + " " + start + " " + arrive);
rout.addTime(id1, start, arrive);
}
//rout.printRout();
//routsystem.addRoute(rout);
}
}
}
Routes.java
import java.util.Vector;
public class Routes {
int id;
String from, to;
Vector<Times> times;
public Routes(int _id, String _from, String _to) {
id = _id;
from = _from;
to= _to;
}
public void addTime(int id, String start, String arrive) {
Times time = new Times();
time.setid(id);
time.setstart(start);
time.setarrive(arrive);
times.add(time);
}
public void printRout() {
System.out.println(id);
System.out.println(from);
System.out.println(to);
for (Times t : times) {
System.out.println(t.getid() + " " + t.getstart() + " " + t.getarrive());
}
}
}
Times.java
public class Times {
int id;
String start, arrive;
public Times() {
id = 0;
start = "";
arrive = "";
}
public int getid() {
return id;
}
public String getstart() {
return start;
}
public String getarrive() {
return arrive;
}
public void setid(int i) {
id = i;
}
public void setstart(String s) {
start = s;
}
public void setarrive(String a) {
arrive = a;
}
}
The problem is you're not initializing your vector before adding objects into it.
That's why you get a nullpointer exception. You should look at what a nullpointer is.
what is a nullpointer exception and how do i fix it.
Hello I'm new to java can anyone help me?
This code convert
2000 to 2k and 1000000 1m etc
private static final NavigableMap<Long, String> suffixes = new TreeMap<>();
static {
suffixes.put(1_000L, "k");
suffixes.put(1_000_000L, "M");
suffixes.put(1_000_000_000L, "G");
suffixes.put(1_000_000_000_000L, "T");
suffixes.put(1_000_000_000_000_000L, "P");
suffixes.put(1_000_000_000_000_000_000L, "E");
}
public String format(long value) {
//Long.MIN_VALUE == -Long.MIN_VALUE so we need an adjustment here
if (value == Long.MIN_VALUE) return format(Long.MIN_VALUE + 1);
if (value < 0) return "-" + format(-value);
if (value < 1000) return Long.toString(value); //deal with easy case
Map.Entry<Long, String> e = suffixes.floorEntry(value);
Long divideBy = e.getKey();
String suffix = e.getValue();
long truncated = value / (divideBy / 10); //the number part of the output times 10
boolean hasDecimal = truncated < 100 && (truncated / 10d) != (truncated / 10);
return hasDecimal ? (truncated / 10d) + suffix : (truncated / 10) + suffix;
}
I need a code which reverse the conversion for example
2k to 2000 and 1m to 1000000
I got the solution just by storing the values in an ArrayList before converting and it worked osum. Thanks for the help everyone :)
I have posted a solution. Need proper input as proper validations are not included. Let me know if it fits your need. also you can add/modify the switch cases according to your need.
public class Test {
public static void main(String[] args) {
String values[] = {
"27",
"999",
"1.0 k",
"110.6 k",
"29.0 G",
"5m",
"5m30",
"2.7k",
"2k7",
"2k17",
"9.2 E",
"9.2EE"
};
Test test = new Test();
test.printValues(values);
}
private void printValues(String[] values) {
for (String value : values) {
if (isProperNumber(value)) {
printValue(value);
} else {
System.out.println("Not a proper number");
}
System.out.println("===================");
}
}
private void printValue(String value) {
String lastAlphabet = value.replaceAll("[^a-zA-Z]*$", "")
.replaceAll(".(?!$)", "");
long multiplier = 1L;
switch (lastAlphabet.toLowerCase()) {
case "k":
multiplier = 1_000L;
break;
case "m":
multiplier = 1_000_000L;
break;
case "g":
multiplier = 1_000_000_000L;
break;
case "t":
multiplier = 1_000_000_000_000L;
break;
case "p":
multiplier = 1_000_000_000_000_000L;
break;
case "e":
multiplier = 1_000_000_000_000_000_000L;
break;
default:
break;
}
String[] values = value.split(lastAlphabet);
if (multiplier == 1) {
System.out.println("" + values[0]);
} else {
double valueMultiplier = Double.parseDouble(values[0]);
double valueAdder;
try {
valueAdder = Double.parseDouble(values[1]);
} catch (ArrayIndexOutOfBoundsException ex) {
valueAdder = 0.0d;
}
double total = (valueMultiplier * multiplier) + valueAdder;
System.out.printf("%.0f\n", total);
}
}
private boolean isProperNumber(String value) {
value = value.replaceAll("\\s+", "");
String count = value.replaceAll("[.0-9]+", "");
return count.length() < 2;
}
}
no need to worry, just use simple JS Trick with Round figure up to 2 decimal places.
function somefunction(count){
if (count >= 1000) {
return Math.round((count/1000) * 10)/10+'k';
} else {
return count;
}
}
if you want put more functionalities, just put more else if with devide 1000 with more million or billion, just 2 or 3 more else if makes your code better.
private static final String dp(String value) {
if (value.contains("k") || value.contains("K")){
value.replace("k", "000");
value.replace("K", "000");
} else if (value.contains("m") || value.contains("M")){
value.replace("m", "000000");
value.replace("M", "000000");
} else if (value.contains("g") || value.contains("G")){
value.replace("g", "000000000");
value.replace("G", "000000000");
} ......
return value;
}
Can anyone help me? How to convert the below Input to JSON Object?
Input :
{ "details": { "device/0/endPointClientName": "ndm-xx-1", "device/1/endPointClientName": "ndm-xx-2", "EnergyMeter/0/current": "20", "EnergyMeter/0/total": "400", } }
Output:-
{ "device": [ {"endPointClientName":"ndm-xx-1" }, {"endPointClientName":"ndm-xx-2" } ], "EnergyMeter": [ {"current":"20", "total":"400"} ] }
I have the Input as JSON Object with Properties class. In the Input we are sharing the FULL PATH. we have to convert this to JSON Object.
[demo]https://jsfiddle.net/CntChen/vh7kat5a/
var input = {
"details": {
"device/0/endPointClientName": "ndm-xx-1",
"device/1/endPointClientName": "ndm-xx-2",
"EnergyMeter/0/current": "20",
"EnergyMeter/0/total": "400",
}
};
function decodeFlatObj(flatOjb) {
var outputObj = {};
for (var key in flatOjb) {
var objNow = outputObj;
var subkey = key.split('/');
for (var i = 0; i < subkey.length - 1; i++) {
// next subkey is number
if (/\d|[1-9]\d*/.test(subkey[i + 1])) {
// current subkey is number
if (/\d|[1-9]\d*/.test(subkey[i])) {
objNow.push([]);
objNow = objNow[parseInt(subkey[i])];
} else {
objNow[subkey[i]] = objNow[subkey[i]] || [];
objNow = objNow[subkey[i]];
}
} else { // next subkey is object
// current subkey is number
if (/\d|[1-9]\d*/.test(subkey[i])) {
objNow[parseInt(subkey[i])] = objNow[parseInt(subkey[i])] || {};
objNow = objNow[parseInt(subkey[i])];
} else {
objNow[subkey[i]] = objNow[subkey[i]] || {};
objNow = objNow[subkey[i]];
}
}
}
var valueDecode;
if (typeof flatOjb[key] === 'object') {
valueDecode = decodeFlatObj(flatOjb[key]);
} else {
valueDecode = flatOjb[key];
}
if (/\d|[1-9]\d*/.test(subkey[subkey.length - 1])) {
objNow[parseInt(subkey[subkey.length - 1])].push(valueDecode);
} else {
objNow[subkey[subkey.length - 1]] = valueDecode;
}
}
return outputObj;
}
var output = decodeFlatObj(input);
console.log(input);
console.log(JSON.stringify(output));
//{"details":{"device":[{"endPointClientName":"ndm-xx-1"},{"endPointClientName":"ndm-xx-2"}],"EnergyMeter":[{"current":"20","total":"400"}]}}
i need to count total doctor transaction using an attribute id, and then total amount payment doctor using an attribute id from list.
how to resolve it? i'm stuck to count it.
please to tell
this is my code:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class SandboxList {
public static void main(String[] args) {
List<Doctor> doctors = new ArrayList<Doctor>();
doctors.add(new Doctor("1726", "John", 10000.00));
doctors.add(new Doctor("4321", "Max", 20000.00));
doctors.add(new Doctor("1726", "John", 40000.00));
doctors.add(new Doctor("4321", "Max", 2000.00));
doctors.add(new Doctor("7765", "Sam", 50000.00));
doctors.add(new Doctor("4321", "Max", 6000.00));
/* I want Output should be Like below
ID : 1726 Name : John Total_payment : 50000.00 total_transaction : 2
ID : 4321 Name : Max Total_payment : 28000.00 total_transaction : 3
ID : 7765 Name : Sam Total_payment : 50000.00 total_transaction : 1
*/
Map<String, List<Doctor>> groupedDoctors = new HashMap<String, List<Doctor>>();
for (Doctor doctor: doctors) {
String key = doctor.doctor_id;
if (groupedDoctors.get(key) == null) {
groupedDoctors.put(key, new ArrayList<Doctor>());
}
groupedDoctors.get(key).add(doctor);
}
Set<String> groupedDoctorsKeySet = groupedDoctors.keySet();
for (String doctorId: groupedDoctorsKeySet) {
List<Doctor> dctrs = groupedDoctors.get(doctorId);
for (Doctor doctor : dctrs) {
System.out.println("ID : "+doctor.doctor_id+"\t"+"Name : "+doctor.doctor_name+"\t"+"total_Payment : "+doctor.doctor_payment);
}
}
}
}
class Doctor {
String doctor_id;
String doctor_name;
Double doctor_payment;
Doctor(String doctor_id, String doctor_name, Double doctor_payment) {
this.doctor_id = doctor_id;
this.doctor_name = doctor_name;
this.doctor_payment = doctor_payment;
}
}
Change the code for:
for (String doctorId : groupedDoctorsKeySet) {
List<Doctor> dctrs = groupedDoctors.get(doctorId);
Double total_payment = 0d;
String doctor_name = null;
for (Doctor doctor : dctrs) {
if (doctor_name == null) {
doctor_name = doctor.doctor_name;
}
total_payment += doctor.doctor_payment;
}
Doctor doctor = new Doctor(doctorId, doctor_name, total_payment);
System.out.println("ID : " + doctor.doctor_id + "\t" + "Name : " + doctor.doctor_name + "\ttotal_Payment : " + doctor.doctor_payment);
}
You could do something like this after you group the doctors:
Set<String> groupedDoctorsKeySet = groupedDoctors.keySet();
for (String doctorId : groupedDoctorsKeySet)
{
List<Doctor> dctrs = groupedDoctors.get(doctorId);
if (dctrs != null && dctrs.size() > 0)
{
StringBuilder sb = new StringBuilder();
sb.append("ID : ").append(doctorId).append("\t").append("Name : ");
sb.append(dctrs.get(0).doctor_name).append("\t").append("total_Payment : ");
double total = 0;
// sum the payment
for (Doctor d : dctrs)
{
total += d.doctor_payment;
}
sb.append(total).append("\t").append("total_transaction : ");
sb.append(dctrs.size());
System.out.println(sb);
}
}
Outputs:
ID : 4321 Name : Max total_Payment : 28000.0 total_transaction : 3
ID : 7765 Name : Sam total_Payment : 50000.0 total_transaction : 1
ID : 1726 Name : John total_Payment : 50000.0 total_transaction : 2
I have used only 2 data structure so that resources can be consume as less as much possible.
class Doctor {
String doctor_id;
String doctor_name;
Double doctor_payment;
Doctor(String doctor_id, String doctor_name, Double doctor_payment) {
this.doctor_id = doctor_id;
this.doctor_name = doctor_name;
this.doctor_payment = doctor_payment;
}
public String getDoctor_id() {
return doctor_id;
}
public String getDoctor_name() {
return doctor_name;
}
public Double getDoctor_payment() {
return doctor_payment;
}
public void setDoctor_id(String doctor_id) {
this.doctor_id = doctor_id;
}
public void setDoctor_name(String doctor_name) {
this.doctor_name = doctor_name;
}
public void setDoctor_payment(Double doctor_payment) {
this.doctor_payment = doctor_payment;
}
/*
HashCode() and equal() method is override because I want to identify the
element in collection on basis of ID's
*/
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Doctor other = (Doctor) obj;
if (doctor_id == null) {
if (other.doctor_id != null)
return false;
} else if (!doctor_id.equals(other.doctor_id))
return false;
return true;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((doctor_id == null) ? 0 :
doctor_id.hashCode());
return result;
}
}
public class SandboxList {
public static void main(String[] args) {
List<Doctor> doctors = new ArrayList<Doctor>();
doctors.add(new Doctor("1726", "John", 10000.00));
doctors.add(new Doctor("4321", "Max", 20000.00));
doctors.add(new Doctor("1726", "John", 40000.00));
doctors.add(new Doctor("4321", "Max", 2000.00));
doctors.add(new Doctor("7765", "Sam", 50000.00));
doctors.add(new Doctor("4321", "Max", 6000.00));
Vector<Doctor> groupedDoctors = new Vector<Doctor>();
Doctor loopVariable;
int index;
for (Doctor doctor : doctors) {
index = groupedDoctors.indexOf(doctor);
// -1 shows groupedDoctors doesn't contain of this doctor
if (-1!=index) {
loopVariable = groupedDoctors.elementAt(index);
groupedDoctors.removeElementAt(index);
loopVariable.setDoctor_payment(doctor.getDoctor_payment() + loopVariable.getDoctor_payment());
groupedDoctors.add(loopVariable);
}
else{
groupedDoctors.addElement(doctor);
}
}
for (Doctor doctor : groupedDoctors) {
System.out.println("ID : " + doctor.doctor_id + "\t" + "Name : " +
doctor.doctor_name + "\t"
+ "total_Payment : " + doctor.doctor_payment);
}
}
}
You may need the code like this:
Set<String> groupedDoctorsKeySet = groupedDoctors.keySet();
if (groupedDoctorsKeySet != null) {
ArrayList<String> list = new ArrayList(groupedDoctorsKeySet);
Collections.sort(list, new Comparator<String>() {
#Override
public int compare(String o1, String o2) {
if (Long.valueOf(o1) < Long.valueOf(o2)) return -1;
else if (Long.valueOf(01) == Long.valueOf(02)) return 0;
else return 1;
}
});
for (String doctorId: list) {
List<Doctor> dctrs = groupedDoctors.get(doctorId);
if (dctrs != null) {
double sum = 0;
String name = null;
for (Doctor doctor : dctrs) {
if (name == null) name = doctor.doctor_name;
sum += doctor.doctor_payment;
}
System.out.println(String.format("ID : %s\tName : %s\tTotal_payment : %.2f total_transaction : %d", new Object[]{doctorId, name, sum, dctrs.size()}));
}
}
}
and the output is:
ID : 1726 Name : John Total_payment : 50000.00 total_transaction : 2
ID : 4321 Name : Max Total_payment : 28000.00 total_transaction : 3
ID : 7765 Name : Sam Total_payment : 50000.00 total_transaction : 1
Using what you already have you could update the grouped section to the below:
Set<String> groupedDoctorsKeySet = groupedDoctors.keySet();
for (String doctorId: groupedDoctorsKeySet) {
List<Doctor> dctrs = groupedDoctors.get(doctorId);
if (dctrs.size() <= 0) { continue; }
Doctor doctor = dctrs.get(0); //These should all be the same doctor due to the key
double totalPayment = 0.0;
for(Doctor doc : dctrs){ totalPayment += doc.doctor_payment; }
System.out.println("ID : " + doctor.doctor_id + "\tName : " + doctor.doctor_name
+ "\ttotal_Payment : " + totalPayment + "\tNumber Of transactions: " + dctrs.size());
}
=========================================================================
Alternative Solution
Alternatively, if the purpose of duplicating the doctors was to be able to examine each payment individually at some point in the future, you could have single Doctor's but with lists of payments. Exposing a method to update the doctor with new payment details
You would then be able to get the number of transactions from the size of that list and the Doctor object would be able to determine the total itself:
class Doctor {
String doctor_id;
String doctor_name;
List<Double> doctor_payments = new ArrayList<>();
Doctor(String doctor_id, String doctor_name, Double doctor_payment) {
this.doctor_id = doctor_id;
this.doctor_name = doctor_name;
this.doctor_payments.add(doctor_payment);
}
public void processPayment(double paymentAmount){
this.doctor_payments.add(paymentAmount);
}
#Override
public String toString(){
double totalPayment = 0.0;
for(Double payment : doctor_payments){ totalPayment += payment; }
return "ID : " + doctor_id + "\tName : " + doctor_name
+ "\ttotal_Payment : " + totalPayment + "\tNumber Of transactions: " + doctor_payments.size();
}
}
Example usage:
Doctor john = new Doctor("1726", "John", 10000.00);
john.processPayment(40000.00);
System.out.println(john);
Output: ID : 1726 Name : John total_Payment : 50000.0 Number Of transactions: 2