How to make JSON having loop inside lopp - java

I have following table client_question table
+----+------------+---------+-----+------+------+
| id | is_deleted | version | cid | pqid | qtid |
+----+------------+---------+-----+------+------+
| 1 | | 0 | 1 | 1 | 1 |
| 2 | | 0 | 1 | 2 | 4 |
| 3 | | 0 | 1 | 2 | 4 |
+----+------------+---------+-----+------+------+
This is Parent_question table
+----+------------+---------+-----+------+
| id | is_deleted | version | pid | qid |
+----+------------+---------+-----+------+
| 1 | | 0 | 1 | 1 |
| 2 | | 0 | 1 | 2 |
| 3 | | 0 | 1 | 3 |
| 4 | | 0 | 1 | 4 |
| 5 | | 0 | 1 | 5 |
| 6 | | 0 | 1 | 6 |
| 7 | | 0 | 2 | 7 |
| 8 | | 0 | 2 | 1 |
| 9 | | 0 | 2 | 2 |
| 10 | | 0 | 2 | 8 |
| 11 | | 0 | 3 | 9 |
| 12 | | 0 | 3 | 1 |
| 13 | | 0 | 3 | 10 |
| 14 | | 0 | 3 | 11 |
| 15 | | 0 | 4 | 12 |
+----+------------+---------+-----+------+
And this is question_option
+----+------------+-----------+---------+
| id | is_deleted | name | version |
+----+------------+-----------+---------+
| 1 | | Excellent | 0 |
| 2 | | Good | 0 |
| 3 | | Fair | 0 |
| 4 | | Poor | 0 |
+----+------------+-----------+---------+
I want to retrieve JSON and send to front end via ajax so
I tried this way
public List<ClientQuestionOption> getSavedQuestionOptions(Long parentId,long clientId)
{
Client client = (Client) entityManagerUtil.find(Client.class, clientId);
List<ClientQuestionOption> questionsList = (List<ClientQuestionOption>)serviceClientDaoImpl.getSavedQuestionOptionsList(parentId,client);
System.out.println("The size is nnnnnnnnnn "+questionsList.size());
List optionsList =new ArrayList();
for(int i=0;i<questionsList.size();i++)
{
//optionsList.add(questionsList.get(i).getCqid().getId());
//optionsList.add(questionsList.get(i).getOid().getName());
Map map=new HashMap();
map.put("qid", questionsList.get(i).getCqid().getPqid().getQid().getId());
map.put("name", questionsList.get(i).getOid().getName());
optionsList.add(map);
}
return optionsList;
}
The JSON i got is like this
[
{
name: "Excellent",
qid: 2
},
{
name: "Poor",
qid: 2
}
],
But I want JSON like this
{
"options": [
"Poot",
"Excellent"
],
"qid": 2
},
Can anybody please tell me how to do so?
edit
Following way I am doing to make JSON
JSONObject object=new JSONObject();
List optionslist=null;
optionslist=(List<ClientQuestionOption>)serviceClientServiceImpl.getSavedQuestionOptions(parentId , Long.valueOf(clientId) );
object.accumulate("optionslist",optionslist );
return object.toString();

First, realise what the function returns (ArrayList) is not JSON at all. It seems that happens elsewhere. You'll need to replace JsonObject() with JsonArray() to change the [..] to '{..}`.
Second, to do the grouping per qid you could write a function that has List<ClientQuestionOption> as input ánd output.

You should check google GSON project, and here is what your code will look like:
public class ClientQuestionOption {
String name;
int qid;
public ClientQuestionOption() {
}
public ClientQuestionOption(String name, int qid) {
this.name = name;
this.qid = qid;
}
}
and then use it this way:
public static void main(String[] args) {
List<ClientQuestionOption> questionOptions = Arrays.asList(
new ClientQuestionOption("Excellent", 1),
new ClientQuestionOption("Excellent", 2),
new ClientQuestionOption("Poor", 3)
);
Gson gson = new GsonBuilder().setPrettyPrinting().create();
System.out.println(gson.toJson(questionOptions));
}
You only need to have Class with same names of fields (or declar Qualifier) and gson will handle conversion from/to json.
here is the output for the above code:
[
{
"name": "Excellent",
"qid": 1
},
{
"name": "Excellent",
"qid": 2
},
{
"name": "Poor",
"qid": 3
}
]

Related

Getting Null values using WindowSpec in spark/java

I have a dataframe :
+----------+------------+------------+--------------------+
| acc |id_Vehicule |id_Device |dateTracking |
+----------+------------+------------+--------------------+
| 1 | 1 | 2 |2020-02-12 14:50:00 |
| 0 | 1 | 2 |2020-02-12 14:59:00 |
| 0 | 2 | 3 |2020-02-12 15:10:00 |
| 1 | 2 | 3 |2020-02-12 15:20:00 |
+----------+------------+------------+--------------------+
I want to get in output :
+----------+------------+------------+--------------------+----------------+
| acc |id_Vehicule |id_Device |dateTracking | acc_previous |
+----------+------------+------------+--------------------+----------------+
| 1 | 1 | 2 |2020-02-12 14:50:00 | null |
| 0 | 1 | 2 |2020-02-12 14:59:00 | 1 |
| 0 | 2 | 3 |2020-02-12 15:10:00 | null |
| 1 | 2 | 3 |2020-02-12 15:20:00 | 0 |
+----------+------------+------------+--------------------+----------------+
I tried the following code :
WindowSpec w =org.apache.spark.sql.expressions.Window.partitionBy("idVehicule","idDevice","dateTracking").orderBy("dateTracking");
Dataset <Row> df= df1.withColumn("acc_previous",lag("acc",1).over(w));
df.show();
I get on result ;
+----------+------------+------------+--------------------+----------------+
| acc |id_Vehicule |id_Device |dateTracking | acc_previous |
+----------+------------+------------+--------------------+----------------+
| 1 | 1 | 2 |2020-02-12 14:50:00 | null |
| 0 | 1 | 2 |2020-02-12 14:59:00 | null |
| 0 | 2 | 3 |2020-02-12 15:10:00 | null |
| 1 | 2 | 3 |2020-02-12 15:20:00 | null |
+----------+------------+------------+--------------------+----------------+
If you have any idea
I will be very grateful
I found the solution, maybe it will help another person.
The problem was because of the "dateTracking" column it should not be like a partitioning column, so I removed it.
WindowSpec w =org.apache.spark.sql.expressions.Window.partitionBy("idVehicule","idDevice").orderBy("dateTracking");
Dataset <Row> df= df1.withColumn("acc_previous",lag("acc",1).over(w));
df.show();

JSprit not using closer vehicle, due to time issues

Single-job schedule with two vehicles. One vehicle starts close to the job, the other starts far from the job. Seems it should prefer to use the closer vehicle, as there's a cost-per-distance. But it uses the farther one, if there's a non-zero setCostPerWaitingTime(). Why?
public void testUseCloserVehicleWhenCostsAreSet() throws Exception {
VehicleType type = VehicleTypeImpl.Builder.newInstance("generic")
.setCostPerDistance(0.017753)
//.setCostPerTransportTime(1.0)
.setCostPerWaitingTime(1.0)
.build();
double serviceTime = 420.0;
Location pointA = Location.newInstance(100.0, 100.0);
Location pointB = Location.newInstance(100.0, 200.0);
Location closeToPointA = Location.newInstance(110.0, 110.0);
Location farFromPointA = Location.newInstance(500.0, 110.0);
VehicleRoutingProblem vrp = VehicleRoutingProblem.Builder
.newInstance()
.setFleetSize(VehicleRoutingProblem.FleetSize.FINITE)
.addVehicle(VehicleImpl.Builder.newInstance("CloseBy")
.setType(type)
.setStartLocation(closeToPointA)
.build())
.addVehicle(VehicleImpl.Builder.newInstance("FarAway")
.setType(type)
.setStartLocation(farFromPointA)
.build())
.addJob(Shipment.Builder.newInstance("123")
.setPickupLocation(pointA)
.setPickupServiceTime(serviceTime)
.setDeliveryLocation(pointB)
.setDeliveryServiceTime(serviceTime)
.setPickupTimeWindow(new TimeWindow(36000.0, 36360.0))
.setDeliveryTimeWindow(new TimeWindow(36360.0, 36720.0))
.setMaxTimeInVehicle(720.0)
.build())
.build();
VehicleRoutingAlgorithm algorithm = Jsprit.Builder.newInstance(vrp)
.buildAlgorithm();
VehicleRoutingProblemSolution bestSolution = Solutions.bestOf(algorithm.searchSolutions());
SolutionPrinterWithTimes.print(vrp, bestSolution, SolutionPrinterWithTimes.Print.VERBOSE);
System.out.flush();
assertEquals("CloseBy", bestSolution.getRoutes().iterator().next().getVehicle().getId());
}
Result:
+----------------------------------------------------------+
| solution |
+---------------+------------------------------------------+
| indicator | value |
+---------------+------------------------------------------+
| costs | 35616.03246830352 |
| noVehicles | 1 |
| unassgndJobs | 0 |
+----------------------------------------------------------+
+--------------------------------------------------------------------------------------------------------------------------------+
| detailed solution |
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| route | vehicle | activity | job | arrTime | endTime | costs |
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| 1 | FarAway | start | - | undef | 0 | 0 |
| 1 | FarAway | pickupShipment | 123 | 400 | 36420 | 35607 |
| 1 | FarAway | deliverShipment | 123 | 36520 | 36940 | 35609 |
| 1 | FarAway | end | - | 37350 | undef | 35616 |
+--------------------------------------------------------------------------------------------------------------------------------+
junit.framework.ComparisonFailure:
Expected :CloseBy
Actual :FarAway
I suspect it has something to do with the vehicle arriving at 400 for a job that can't start until 36000. Is there a way to prevent that, so the vehicle starts only as early as needed to reach the first job? Does setCostPerWaitingTime do something other than what I think?
Here's a comparison of the job with only the CloseBy vehicle.
+--------------------------------------------------------------------------------------------------------------------------------+
| detailed solution |
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| route | vehicle | activity | job | arrTime | endTime | costs |
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| 1 | FarAway | start | - | undef | 0 | 0 |
| 1 | FarAway | pickupShipment | 123 | 400 | 36420 | 35607 |
| 1 | FarAway | deliverShipment | 123 | 36520 | 36940 | 35609 |
| 1 | FarAway | end | - | 37350 | undef | 35616 |
+--------------------------------------------------------------------------------------------------------------------------------+
+--------------------------------------------------------------------------------------------------------------------------------+
| detailed solution |
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| route | vehicle | activity | job | arrTime | endTime | costs |
+---------+----------------------+-----------------------+-----------------+-----------------+-----------------+-----------------+
| 1 | CloseBy | start | - | undef | 0 | 0 |
| 1 | CloseBy | pickupShipment | 123 | 14 | 36420 | 35986 |
| 1 | CloseBy | deliverShipment | 123 | 36520 | 36940 | 35988 |
| 1 | CloseBy | end | - | 37031 | undef | 35989 |
+--------------------------------------------------------------------------------------------------------------------------------+
I think the problem is that the CloseBy vehicle arrives sooner, so it pays higher wait costs, while the other vehicle is driving during that time so pays less in wait costs. This would be mitigated if the vehicle didn't start until it needed to, but I'm unsure how to set that up.

what is the unique id of informix temp table?

I create a temp table which consist of several table with UNION ALL statement like here below. I want later map this table to the entity for repository in spring. With other words I wanna map temp table to entity in spring jpa or hibernate.
select * from name UNION ALL
select * from soft where id >3
into temp namesoft_tmp
I tried the following.
select * from namesoft_tmp
but i can't see what is the column which can point me to the conclusion that this is primary key.
What is the unique id(primary key) of table namesoft_tmp?
How can i add auto generated id to temp table?
How can i excute select statement based on unique id?**
In general, the result of a UNION ALL query does not have a primary key; there is no guarantee that there are not duplicate rows in the result set.
Imagine a table describing the table of elements — called elements.
SELECT * FROM elements WHERE atomic_number < 10
UNION ALL
SELECT * FROM elements WHERE symbol MATCHES '[A-F]*'
INTO TEMP union_all;
Here, the elements Boron (B), Carbon (C), Beryllium (Be) and Fluorine (F) are all listed twice.
However, you can use:
SELECT ROWID, * FROM union_all ORDER BY atomic_number;
to get a unique identifier, the ROWID, in the result set. Note that this unique identifier is unique at any given time, but is not guaranteed to be stable. If you delete rows and add them again, the ROWID of the replaced rows may be different from before. But the ROWID will be unique until you edit the table.
+-------+--------+--------+--------------+-----------+--------+-------+
| rowid | atomic | symbol | name | atomic | period | group |
| | number | | | weight | | |
+-------+--------+--------+--------------+-----------+--------+-------+
| 257 | 1 | H | Hydrogen | 1.0079 | 1 | 1 |
| 258 | 2 | He | Helium | 4.0026 | 1 | 18 |
| 259 | 3 | Li | Lithium | 6.9410 | 2 | 1 |
| 260 | 4 | Be | Beryllium | 9.0122 | 2 | 2 |
| 266 | 4 | Be | Beryllium | 9.0122 | 2 | 2 |
| 267 | 5 | B | Boron | 10.8110 | 2 | 13 |
| 261 | 5 | B | Boron | 10.8110 | 2 | 13 |
| 268 | 6 | C | Carbon | 12.0110 | 2 | 14 |
| 262 | 6 | C | Carbon | 12.0110 | 2 | 14 |
| 263 | 7 | N | Nitrogen | 14.0070 | 2 | 15 |
| 264 | 8 | O | Oxygen | 15.9990 | 2 | 16 |
| 265 | 9 | F | Fluorine | 18.9980 | 2 | 17 |
| 269 | 9 | F | Fluorine | 18.9980 | 2 | 17 |
| 270 | 13 | Al | Aluminium | 26.9820 | 3 | 13 |
| 271 | 17 | Cl | Chlorine | 35.4530 | 3 | 17 |
| 272 | 18 | Ar | Argon | 39.9480 | 3 | 18 |
| 273 | 20 | Ca | Calcium | 40.0780 | 4 | 2 |
| 274 | 24 | Cr | Chromium | 51.9960 | 4 | 6 |
| 275 | 26 | Fe | Iron | 55.8450 | 4 | 8 |
| 276 | 27 | Co | Cobalt | 58.9330 | 4 | 9 |
| 277 | 29 | Cu | Copper | 63.5460 | 4 | 11 |
| 278 | 33 | As | Arsenic | 74.9220 | 4 | 15 |
| 279 | 35 | Br | Bromine | 79.9040 | 4 | 17 |
| 280 | 47 | Ag | Silver | 107.8700 | 5 | 11 |
| 281 | 48 | Cd | Cadmium | 112.4100 | 5 | 12 |
| 282 | 55 | Cs | Caesium | 132.9100 | 6 | 1 |
| 283 | 56 | Ba | Barium | 137.3300 | 6 | 2 |
| 284 | 58 | Ce | Cerium | 140.1200 | 6 | L |
| 285 | 63 | Eu | Europium | 151.9600 | 6 | L |
| 286 | 66 | Dy | Dyprosium | 162.5000 | 6 | L |
| 287 | 68 | Er | Erbium | 167.2600 | 6 | L |
| 288 | 79 | Au | Gold | 196.9700 | 6 | 11 |
| 289 | 83 | Bi | Bismuth | 208.9800 | 6 | 15 |
| 290 | 85 | At | Astatine | 209.9900 | 6 | 17 |
| 291 | 87 | Fr | Francium | 223.0200 | 7 | 1 |
| 292 | 89 | Ac | Actinium | 227.0300 | 7 | A |
| 293 | 95 | Am | Americium | 243.0600 | 7 | A |
| 294 | 96 | Cm | Curium | 247.0700 | 7 | A |
| 295 | 97 | Bk | Berkelium | 247.0700 | 7 | A |
| 296 | 98 | Cf | Californium | 251.0800 | 7 | A |
| 297 | 99 | Es | Einsteinium | 252.0800 | 7 | A |
| 298 | 100 | Fm | Fermium | 257.1000 | 7 | A |
| 299 | 105 | Db | Dubnium | 270.1300 | 7 | 5 |
| 300 | 107 | Bh | Bohrium | 270.1300 | 7 | 7 |
| 301 | 110 | Ds | Darmstadtium | 281.1700 | 7 | 10 |
| 302 | 112 | Cn | Copernicium | 285.1800 | 7 | 12 |
| 303 | 114 | Fl | Flerovium | 289.1900 | 7 | 14 |
+-------+--------+--------+--------------+-----------+--------+-------+

Iterating through lists of list in java

I have two tables User and Roles with one-to-one relation as below.
User
_________________________________________
| Id | user_name | full_name | creator |
_________________________________________
| 1 | a | A | a |
| 2 | b | B | a |
| 3 | c | C | a |
| 4 | d | D | c |
| 5 | e | E | c |
| 6 | f | F | e |
| 7 | g | G | e |
| 8 | h | H | e |
| 9 | i | I | e |
|10 | j | J | i |
_________________________________________
Roles
_______________________________________
| id | user_mgmt | others | user_id |
_______________________________________
| 1 | 1 | 1 | 1 |
| 2 | 0 | 1 | 2 |
| 3 | 1 | 0 | 3 |
| 4 | 0 | 1 | 4 |
| 5 | 1 | 1 | 5 |
| 6 | 0 | 1 | 6 |
| 7 | 0 | 0 | 7 |
| 8 | 0 | 0 | 8 |
| 9 | 1 | 0 | 9 |
________________________________________
The Roles table have boolean columns, so if an User have user_mgmt role he can add many users (How many users can be added by an user is not definite). I want to fetch all users created by an user and his child users ( a is parent, c is child of a and e is child of c ..) .
Here is my code to fetch users
public void loadUsers(){
List<Users> users = new ArrayList<>();
String creator = user.getUserName();
List<Users> createdUsers = userService.getUsersByCreator(creator);
for(Users user : createdUsers) {
Roles role = createdUsers.getRoles();
if(role.isEmpMgnt()){
users.add(user);
loadUsers();
}
}
}
This gives me an stack overflow error. If i don't call loadUsers() recursively it returns only a single child result. So is there any solutions to this ? Thanks for any help in advance.
This gives you stack overflow error because a has creator a. So you have infinite loop for user a. For a you should set creator to null or skip self references in code.
Also you should pass current user into loadUsers() method and read only users that are created by it. Like
public void loadUsers(String creator)
and only process users created by that creator. Here
String creator = user.getUserName();
what is user? You should use creator. Question is how do you obtain initial creator. Probably initial creator should be user where creator is null.

How to limit ArrayList to 15?

I have 2 array lists. i iterate through list1 and store the data that matches the seat_no to the index of list2.
list1 contains:
|seat_no | id |
===================
| 1 | 001 |
| 2 | 002 |
| 3 | 003 |
| 4 | 004 |
| 7 | 005 |
| 10 | 006 |
| 11 | 007 |
list2 contains:
|index | id | seat_no |
=============================
| 1 | 001 | 1 |
| 2 | 002 | 2 |
| 3 | 003 | 3 |
| 4 | 004 | 4 |
| 5 |"blank" |"blank" |
| 6 |"blank" |"blank" |
| 7 | 005 | 7 |
| 8 |"blank" |"blank" |
| 9 |"blank" |"blank" |
| 10 | 006 | 10 |
| 11 | 007 | 11 |
what list2 should contain:
where list2 must have a limit of 15
|index | id | seat_no |
=============================
| 1 | 001 | 1 |
| 2 | 002 | 2 |
| 3 | 003 | 3 |
| 4 | 004 | 4 |
| 5 |"blank" |"blank" |
| 6 |"blank" |"blank" |
| 7 | 005 | 7 |
| 8 |"blank" |"blank" |
| 9 |"blank" |"blank" |
| 10 | 006 | 10 |
| 11 | 007 | 11 |
| 12 |"blank" |"blank" |
| 13 |"blank" |"blank" |
| 14 |"blank" |"blank" |
| 15 |"blank" |"blank" |
Here's my code so far... pls help me.. i plan to use array but i don't know if its applicable to my codes now..
ViewGridObject.java
public class ViewGridObject
{
public String stud_id, seat_no;
public ViewGridObject(String stud_id, String seat_no)
{
this.stud_id = stud_id;
this.seat_no = seat_no;
}
}
main.java
ArrayList<HashMap<String, String>> to_take = new ArrayList<HashMap<String, String>>();
try
{
JSONObject jArray = new JSONObject(result);
JSONArray stud_info = jArray.getJSONArray("stud_info");
ca_list = new ArrayList<ViewGridObject>();
for (int i = 0; i < stud_info.length(); i++)
{
HashMap<String, String> map = new HashMap<String, String>();
JSONObject e = stud_info.getJSONObject(i);
map.put("id", String.valueOf(i));
map.put("stud_id", e.getString("student_id"));
map.put("seat_no", e.getString("seat_no"));
to_take.add(map);
ca_list.add(new ViewGridObject(e.getString("student_id"), e.getString("seat_no")));
}
List<ViewGridObject> list2 = new ArrayList<ViewGridObject>();
int i1 = 0;
for (ViewGridObject o : ca_list) {
for (i1++; !o.seat_no.equals(i1 + ""); i1++) {
list2.add(new ViewGridObject(null, 0, i1 + ""));
}
list2.add(o);
}
List<ViewGridObject> list2 = new ArrayList<ViewGridObject>();
for(int i=0;i<50;i++) {
try {
list2.add(list1.get(i));
} catch(Exception rr) {
list2.add(new ViewGridObject("blank","blank");
}
}
You can limit that only when you explicitly check that before you add,
or by creating a new MyArrayList where you have an ArrayLIst integrated, but in add() you do not add when size is > 15; you could return false in that case.
I suggest use the "check that before you ad"d approach:
int limit = 15;
if (list.size() < limit) {
list.add(value);
}
Arraylist are boundless by implementation. Couple of options;
Use an array and use Arrays.asList to perform arraylist functions
Implement AbstractList and implement the add method like
if (size()> getBoundedSize())
Let me know if you need a clearer example
Using Java 8, you can convert the ArrayList to a Stream and limit it:
List<Object> largerArray = Arrays.asList(members);
largerArray.stream()
.limit(3)
.forEach(member -> {
// ...
});

Categories