Batching in Java and Excel gives different results - java

I need to batch elements that have similar client id (String type, but at the moment only numeric values, like "12345", "235134", etc.)
Map<String, List<Client>> _batched = new HashMap<String, List<Client>>();
for (Client c : _Clients)
{
String id = c.getIdClient();
List<Client> clients = _batched.get(id);
if(_clients == null){
clients = new ArrayList<Client>();
_batched.put(id, clients);
}
clients.add(c);
}
The problem is that when I compare this function with the results of Excel (=SUM(IF(FREQUENCY(C2:C618,C2:C618)>0,1))), then I get different results, i.e. 526 and 519.
Is something wrong with my code?

Your problem is here:
String id = c.getIdClient();
List<Client> _clients = _batched.get(id);
if(_clients == null){
pois = new ArrayList<Client>();
_batched.put(id, _clients);
}
_clients.add(c);
You create a new array into a variable called pois but then put the contents of the variable _clients into _batched. What happens with the value put into pois?
I don't understand how that doesn't null pointer exception actually.

Related

How do I handle Java NoSuchFieldException?

I am trying to loop through request body keys and set values of an object when the key and an object field correlate like so:
User user = new User((String) super.session.get("id"));
Class<?> c = user.getClass();
for(String key : super.body.keySet()){
Field f = c.getField(key);
if(f != null){
if(key.equals("avatar")){
uploadFile();
}
f.set(user, super.body.get(key));
}
}
user.update();
However, I keep getting the NoSuchFieldException and my code stops working. How can I deal with the possibility of a field not existing?

getting all worksheets data using java

I have a google spreadsheet which contains 2 or more worksheets. I am able to print all tabs name or worksheets name using java. I'm looking for a way to print all worksheet data by default it prints only first tab or worksheet. I am attaching my code below plz someone helps me I am pretty new to this code snippet
You need to specify the range first, then return the data in a ValueRange object. See example code below
String range = "UK!A2:E";
ValueRange response = service.spreadsheets().values()
.get(spreadsheetId, range)
.execute();
List<List<Object>> values = response.getValues();
if (values == null || values.isEmpty()) {
System.out.println("No data found.");
} else {
for (List row : values) {
Iterator<Object> elem = row.iterator();
while (elem.hasNext()) {
System.out.println(elem.next());
}
}
}

Java/Mysql: Get all resulted lines from a stored procedure and not only the last

I have a stored procedure in mysql that returns more than one lines.
My java code to execute it is:
preparedStmt = conn.prepareCall(queryString);
preparedStmt.setString(1, String.valueOf(patient_id));
//System.out.print("select patient data java file 1 ");
boolean results = preparedStmt.execute();
int rowsAffected = 0;
// Protects against lack of SET NOCOUNT in stored procedure
while (results || rowsAffected != -1) {
if (results) {
rs = preparedStmt.getResultSet();
break;
} else {
rowsAffected = preparedStmt.getUpdateCount();
}
results = preparedStmt.getMoreResults();
}
int i = 0;
obj = new JSONObject();
while (rs.next()) {
JSONArray alist = new JSONArray();
alist.put(rs.getString("patient_id"));
alist.put(rs.getString("allergy"));
alist.put(rs.getString("allergy_description"));
alist.put(rs.getString("allergy_onset_date"));
alist.put(rs.getString("agent_description"));
alist.put(rs.getString("agent"));
alist.put(rs.getString("severity"));
obj.put("ps_allergies", alist);
i++;
}
conn.close();
At the end, ps_allergies json object contains only the last line of the query. This is the print output:
["1","week",null,"2017-07-07","vacation home","test2","mobile contact"]
I want ps_allergies to contain something similar to
[["1","hydrogen peroxide","Nuts","2017-07-04","Nursing profressionals","43","Paramedical practinioners"],["1","week",null,"2017-07-07","vacation home","test2","mobile contact"]...]
Do you know how to fix this?
Not exactly knowing what library you use, but it might have something to do with this line:
obj.put("ps_allergies", alist);
A put method in general associates the specified value with the specified key in a map. Since you are constantly overwriting you key 'ps_allergies' in the loop it will only retain the last value.
You might want to associate a list/array to ps_allergies and you then add every alist object in this list/array.
I found the solution. Instead of put I'm using append method.
obj.append("ps_allergies", alist);
The resulted output now is:
[["1","hydrogen peroxide","Nuts","2017-07-04","Nursing professionals","43","Paramedical practitioners"],["1","chlorhexidine","test123","2017-07-15","mobile contact","test232","pager"],["1","Resistance to unspecified antibiotic","Feb3","2017-03-02","mobile contact","test232","pager"],["1","week",null,"2017-07-07","vacation home","test2","mobile contact"]]

MongoDB update with layered JSON - how to efficiently? Dot notation?

Mongodb has an update function, where it can increment pre-existing fields. However, I found that it could only update flat JSON. Whenever there's a JSONObject inside of a JSONObject, with a value I want to increment, I can't actually seem to do it. It will return this error:
com.mongodb.WriteConcernException: Write failed with error code 14 and error message
'Cannot increment with non-numeric argument: {laneQty: { BOTTOM: 1 }}'
As you can see, I tried update incrementing laneQty.BOTTOM by 1. I don't want to write an algorithm to change every single layered json field into dot notation(like laneQty.BOTTOM), so is there a way to either turn the JSON into dot notation pre-upsert?
For now my general upsert function looks like this:
public boolean incrementJson(BasicDBObject json, String colName, ArrayList<String> queryParams, ArrayList<String> removeParams){
/*make sure the game id AND the main player id can't both be the same.
If either/or, it's fine. We don't want duplicates.
*/
BasicDBObject query = new BasicDBObject();
DBCollection collection = db.getCollection(colName);
for(int i = 0; i < queryParams.size(); i++){
String param = queryParams.get(i);
query.put(param, json.get(param));
}
for(String param : removeParams){
json.remove(param);
}
return collection.update(query, new BasicDBObject("$inc", json), true, false).isUpdateOfExisting();
}
Is there any suggested upgrades to this code that could make it easily update layered json as well? Thank you!
By the way, it'll be very hard for me to hardcode this. There are a ton of layered objects and that would take me forever. Also, I am not in complete control of which fields are populated in the layers, so I can't just say laneQty.BOTTOM every single time because it will not always exist. Prior to upserting, the BasicDBObject json was actually a java bean parsed into BasicDBObject. This is its constructor if it's of any help:
public ChampionBean(int rank, int division, int assists, int deaths, int kills, int qty, int championId,
HashMap<String, Integer> laneQty, HashMap<String, Integer> roleQty,
ParticipantTimelineDataBean assistedLaneDeathsPerMinDeltas,
ParticipantTimelineDataBean assistedLaneKillsPerMinDeltas, ParticipantTimelineDataBean creepsPerMinDeltas,
ParticipantTimelineDataBean csDiffPerMinDeltas, ParticipantTimelineDataBean damageTakenDiffPerMinDeltas,
ParticipantTimelineDataBean damageTakenPerMinDeltas, ParticipantTimelineDataBean goldPerMinDeltas,
ParticipantTimelineDataBean xpDiffPerMinDeltas, ParticipantTimelineDataBean xpPerMinDeltas, int wins,
int weekDate, int yearDate) {
super();
this.rank = rank;
this.division = division;
this.assists = assists;
this.deaths = deaths;
this.kills = kills;
this.qty = qty;
this.championId = championId;
this.laneQty = laneQty;
this.roleQty = roleQty;
this.assistedLaneDeathsPerMinDeltas = assistedLaneDeathsPerMinDeltas;
this.assistedLaneKillsPerMinDeltas = assistedLaneKillsPerMinDeltas;
this.creepsPerMinDeltas = creepsPerMinDeltas;
this.csDiffPerMinDeltas = csDiffPerMinDeltas;
this.damageTakenDiffPerMinDeltas = damageTakenDiffPerMinDeltas;
this.damageTakenPerMinDeltas = damageTakenPerMinDeltas;
this.goldPerMinDeltas = goldPerMinDeltas;
this.xpDiffPerMinDeltas = xpDiffPerMinDeltas;
this.xpPerMinDeltas = xpPerMinDeltas;
this.wins = wins;
this.weekDate = weekDate;
this.yearDate = yearDate;
}
The participantTimelineDataBean is another bean with 4 int fields inside of it. I want to increment those fields (so yes it's only 2 layers deep, so if there's a solution with 2 layers deep availability I'll take that too).
Use the dot-notation:
new BasicDBObject("$inc", new BasicDBObject("laneQty.BOTTOM", 1) )
Alternative quick&dirty solution: Just collection.save the whole document under the same _id.
Use this library:
https://github.com/rhalff/dot-object
For example if you have an object like this:
var jsonObject = {
info : {
firstName : 'aamir',
lastName : 'ryu'
email : 'aamiryu#gmail.com'
},
}
then your node.js code would be like this:
var dot = require('dot-object');
var jsonObject = // as above ;-);
var convertJsonObjectToDot = dot.dot(jsonObject);
console.log(convertJsonObjectToDot);
Output will be as shown below:
{
info.firstName : 'aamir',
info.lastName : 'ryu',
info.email : 'aamiryu#gmail.com
}
Please bear with me, this is my first answer on stackoverflow ever, since i was searching for the same thing and i found one solution to it, hope it helps you out.

How to Update an Existing Record in a Dataset

I can't seem to update an existing record in my table using a strongly-typed dataset. I can add a new record, but if I make changes to an existing record it doesn't work.
Here is my code:
private void AddEmplMaster()
{
dsEmplMast dsEmpMst = new dsEmplMast();
SqlConnection cn = new SqlConnection();
cn.ConnectionString = System.Configuration.ConfigurationSettings.AppSettings["cn.ConnectionString"];
SqlDataAdapter da1 = new SqlDataAdapter("SELECT * FROM UPR00100", cn);
SqlCommandBuilder cb1 = new SqlCommandBuilder(da1);
da1.Fill(dsEmpMst.UPR00100);
DataTable dtMst = UpdateEmpMst(dsEmpMst);
da1.Update(dsEmpMst.UPR00100);
}
This procedure is called from above to assign the changed fields to a record:
private DataTable UpdateEmpMst(dsEmplMast dsEmpMst)
{
DataTable dtMst = new DataTable();
try
{
dsEmplMast.UPR00100Row empRow = dsEmpMst.UPR00100.NewUPR00100Row();
empRow.EMPLOYID = txtEmplId.Text.Trim();
empRow.LASTNAME = txtLastName.Text.Trim();
empRow.FRSTNAME = txtFirstName.Text.Trim();
empRow.MIDLNAME = txtMidName.Text.Trim();
empRow.ADRSCODE = "PRIMARY";
empRow.SOCSCNUM = txtSSN.Text.Trim();
empRow.DEPRTMNT = ddlDept.SelectedValue.Trim();
empRow.JOBTITLE = txtJobTitle.Text.Trim();
empRow.STRTDATE = DateTime.Today;
empRow.EMPLOYMENTTYPE = "1";
dsEmpMst.UPR00100.Rows.Add(empRow);
}
catch { }
return dtMst;
}
Thank you
UPDATE:
Ok I figured it out. In my UpdateEmpMst() procedure I had to check if the record exists then to retrieve it first. If not then create a new record to add. Here is what I added:
try
{
dsEmplMast.UPR00100Row empRow;
empRow = dsEmpMst.UPR00100.FindByEMPLOYID(txtEmplId.Text.Trim());
if (empRow == null)
{
empRow = dsEmpMst.UPR00100.NewUPR00100Row();
dsEmpMst.UPR00100.Rows.Add(empRow);
}
then I assign my data to the new empRow I created and updates fine.
In order to edit an existing record in a dataset, you need to access a particular column of data in a particular row. The data in both typed and untyped datasets can be accessed via the following:
With the indices of the tables, rows, and columns collections.
By passing the table and column names as strings to their respective collections.
Although typed datasets can use the same syntax as untyped datasets, there are additional advantages to using typed datasets. For more information, see the "To update existing records using typed datasets" section below.
To update existing records in either typed or untyped datasets
Assign a value to a specific column within a DataRow object.
The table and column names of untyped datasets are not available at design time and must be accessed through their respective indices.

Categories

Resources