This is my dataset,
Name Group Age
A [123] 10
B. [123,456] 20
C. [456,789] 30
D. [900] 40
E. [800,900] 50
F. [1000] 60
Now I want to merge Group such that, the result looks like
Name Group Age
A,B,C [123,456,789] 10,20,30
D,E [900,800] 40,50
F. [1000] 60
I tried arrays contains but that is not giving me what I want. I tried self join too. Anyone can help with a java solution.
Edit:
I found ReduceFunction which can do something similar.
dataset.reduce(new ReduceFunction<Grouped>(){
private static final long serialVersionUID = 8289076985320745158L;
#Override
public Grouped call(final Grouped v1, final Grouped v2) {
if (!Collections.disjoint(v1.getGroup(), (v2.getGroup())))
{
v1.getAge().addAll(v2.getAge());
v1.getGroup().addAll(v2.getGroup());
v1.getName().addAll(v2.getName());
}
}
}
But how to do this for all rows???
This is able to give me first 2 rows reduced to :
Name Group Age
A,B [123,456] 10,20
Related
I have an array list consisting of objects defined in the class Result(date, name, grade). I have managed to sort the dataset. However I want there to be no duplicates, only the object with that has highest grade attribute should be left. I have tried several codes but it gets me no where.
The data looks as following now,
DATE NAME GRADE
0612 AA BB 15
0713 AA BB 12
0613 CD E 7
0327 KA BC 23
0903 KA BC 15
But i want it to look like this
0612 AA BB 15
0613 CD E 7
0327 KA BC 23
Result class defined as below
Result(int date,String name, String grade){
this.date=date;
this.name=first;
this.grade=grade;
}
for (Result element:info) {
if (!newList.contains(element.name)) {
newList.add(element);
}
}
for(Result st:newList){
System.out.println(st.date+" "+st.name+" " + st.grade);
}
}
}
I have done this, so far. However it does not give me the wanted output.
You can take advantage of Java streams API. Grouping the values by name and getting the highest grade:
Map<String, Result> map = newSet.stream()
.collect(Collectors.toMap(Result::getName, Function.identity(),
BinaryOperator.maxBy(Comparator.comparing(Result::getGrade))));
I've tested it using the following:
Result r1 = new Result(1, "Emmanuel", "14");
Result r2 = new Result(2, "Emmanuel", "15");
And the result is:
{Emmanuel=Result{date=2, name='Emmanuel', grade='15'}}
I have set and a sub-set for each id. i need to accumulate the total
ex: employeeIdSet is the outer set which has all the employeeIds
Now each employee - may be combined or not combined and they will be added credits
empa - credit 10
empb linked with empc, empd - credit would be 15, overall for the 3 employees.
similalrly
empe linked with empz, emps - credit would be 7, over all for the 3 employees and linked with empq where the credit is 9
similarly
empr linked with empo - credit would be 6, overall for the 2 employees
Now i want to have a list of employee id with respective credits
ex:
empa-10
emp-15,
empc-15,
empd-15,
empe - 7+9,
empz - 7+9,
emps- 7+9,
empr - 6,
empo - 6
the problem we get employee id in the outer loop and inner loop we can get the subsequent employees. however all addition leads to problem
code
final Set<Long> combinedEmployeeIdSet = new HashSet<>();
final Set<CombinedEmployee> combinedEmployees = employee.getCombinedEmployees();
for(final CombinedEmployee combinedEmployee: combinedEmployees) {
combinedEmployeeIdSet.add(combinedEmployee.getId());
}
for(final OtherEmployee otherEmployee: otherEmployees) {
if(!combinedEmployeeIdSet.contains(otherEmployee.getId())) {
employeeCredit += otherEmployee.getCredit();
}
}
expectation is get the total credits of the given employeeId where when there under same group, it should be added as one single unit, else the credit should be added
empe - 7+9, displays 15
empz - 7+9, displays 15
emps- 7+9, displays 15
thanks
Very confused by your description.
Do you mean you have some "emp"s, say: emp-a,emp-b ... emp-x, and each emp have a credit, say: emp-a:10, emp-b:5, emp-c:7... emp-x:6. Some emps have links with other emps, say: emp-a (emp-b, empc). Now you want to get the credit for each emp, if the emp has links, its credit should be a sumarize of itself and all its links.
So you may get
emp-a 10+5+7
emp-b 5
emp-c 7
...
emp-x 6
I have a list which is a java object like below.
public class TaxIdentifier {
public String id;
public String gender;
public String childId;
public String grade,
public String isProcessed;
////...///
getters and setters
///....///
}
Records in DB looks like below,
id gender childId grader isProcessed
11 M 111 3 Y
12 M 121 4 Y
11 M 131 2 Y
13 M 141 5 Y
14 M 151 1 Y
15 M 161 6 Y
List<TaxIdentifier> taxIdentifierList = new ArrayList<TaxIdentifier>();
for (TaxIdentifier taxIdentifier : taxIdentifierList) {
}
while I process for loop and get the id = 11, i have to check if there are other records with id = 11 and process them together and do a DB operation and then take the next record say in this case 12 and see if there are other records with id = 12 and so on.
One option is i get the id and query the DB to return all id = 11 and so on.
But this is too much back and forth with the DB.
What is the best way to do the same in java? Please advice.
If you anyway need to process all the records in the corresponding database table - you should retrieve all of them in 1 database roundtrip.
After that, you can collect all your TaxIdentifier records in dictionary data structure and process in whatever way you want.
The brief example may look like this:
Map<String, List<TaxIdentifier>> result = repositoty.findAll().stream().collect(Collectors.groupingBy(TaxIdentifier::getId));
Here all the TaxIdentifier records are grouped by TaxIdentifier's id (all the records with id equals "11") can be retrieved and processed this way:
List<TaxIdentifier> taxIdentifiersWithId11 = result.get("11");
I would leverage the power of your database. When you query, you should order your query by id in ascending order. Not sure which database you are using but I would do:
SELECT * FROM MY_DATABASE WHERE IS_PROCESSED = 'N' ORDER BY ID ASC;
That takes the load of sorting it off of your application and onto your database. Then your query returns unprocessed records with the lowest id's on top. Then just sequentially work through them in order.
I am using Java, MySQL and iReport-3.7.6. I need to create a report with two tables. One contains Machine Production details other contains employees working in a shift. It should print date and shift wise.
I can merge employees against machines. Because there are one or more employees works in two or three same machines.
I need to get a report like the one below.
Date:04-03-2015 Shift - I
Sno Supervisor Machines Employees
-----------------------------------------------------------
1 Arun 1,2,4 Siva,Raj,Ram,James
2 Kumar 3,5 Balu,Mano,Stephan
Sno Machines WorkMins Production_kg
--------------------------------------------
1 1 480 800
2 2 300 500
3 3 480 1200
4 4 480 900
5 5 480 1000
and then only Date:04-03-2015 Shift - II, and so on.
If I use sub report concept, for example, I am giving for one day report means, it prints like employee table for all shift and then production table for shift on that day. But I need to print as above.
Can someone give me a solution to overcome this problem?
I think you can use a sub report, I know that you need a HashMap to build a sub report, then I propose the following:
1.- Create three classes:
public class RowEmployee {
private int sno;
private String supervisor;
private int [] machines;
private String [] employees;
// getters and setters
}
public class RowMachinesDetails {
private int sno;
private int machine;
private int workMins;
private int productinKg;
// getters and setters
}
public class Shift {
private Date dateShift;
private List<TableEmployee> listTableEmployee;
private List<TableMachinesDetails> listTableMachinesDetails;
// getters and setters
}
The RowEmployee class is for the first table, the RowMachinesDetails is for the second table and the Shift class is for each shift of your report. As you can see, the Shift class has a list of RowEmployee and a list of RowMachinesDetails, because these lists correspond to each table, also it has a date which corresponds to date of the shift.
2.- Fill your lists with data of employee and data of production
List<TableEmployee> listTableEmployee = new ArrayList<TableEmployee>();
List<TableMachinesDetails> listTableMachinesDetails = new ArrayList<TableMachinesDetails>();
//Create instances of TableEmployee and TableMachinesDetails, and fill your lists
listTableEmployee.add(TableEmployee);
listTableMachinesDetails(TableMachinesDetails);
3.- Create instances of Shift and fill your HashMap with these instances, put the number of shift as key in the HashMap.
//Create instances of Shift
Shift shift = new Shift();
shift.setDateShitf (dateShift);
shift.setListTableEmployee(listTableEmployee);
shift.setListTableMachinesDetails(listTableMachinesDetails);
//Fill the HashMap
hashMapShift.add("I", shift);
4.- Finally, create your datasource as HashMap in iReport and use hashMapShift to fill your datasource.
NOTE: Maybe the type of variables aren't appropiate, the most important is the concept of the solution.
I hope this helps you.
Good Luck.
I'm making a program to make a list of people, with 3 different marks of time (in double)
To do it, I made 4 arrays, One String, to save people names, and 3 Doubles to save the 3 marks on the years 2010, 2011, and 2012.
In the menu, I have to implement an option to sort the list on 2012s mark, in descending order.
Like this
m12[0] = 12.1
m12[1] = 34.1
m12[2] = 23.1
m12[3] = 23.5
into:
m12[1] = 34.1
m12[3] = 23.5
m12[2] = 21.1
m12[0] = 12.1
I did it with a basic algorithm, but now I want to know if it's possible to get the actual order of the arrays, ([1],[3],[2],[0]) and apply it to the other arrays I have to print it as a list based on the 2012 mark in descending order.
Thats the code I have to make the normal order list:
if(option==2){
System.out.println("# , Name, 2010, 2011, 2012");
for(i=0;i<dorsal.length-1;i++){
if(dorsal[i]!=0){
System.out.println(dorsal[i]+"- "+nom[i]+", "+m10[i]+", "+m11[i]+", "+m12[i] );
}
}
System.out.println("Press ENTER to return");
intro.nextLine();
}
Sorry if I didnt explained it very good, I started programming 3 months ago and I'm so newbie.
//EDIT
I'll paste here the head of the exercise:
Thats exactly the programs needs to do. I'm stucked at point 3.
The objective is to develop a program to manage a list of members of
in a competition of long jump. The number of places available is 15.
Their data will be introduced in the same order in which the athletes
enroll. Design a program that shows the following options:
1 – Register a participant
2 – List all the participant’s data
3 – List all the participant’s data by mark
4 – Quit
If 1 is selected, data of one of the participants will be introduced:
Name, best mark in 2012, best mark in 2011 and best mark in 2010.
If 2 is selected, we have to list all participant’s data ordered by dorsal
number (the order they’ve enrolled)
If 3 is selected, we have to list all participant’s data ordered by 2012
mark, from greater to smaller.
After processing each option, the main menu must be shown again,
till the option 4 is selected, quitting the program.
Thanks.
Define a class to contain the data for each person, such as:
public class Person
{
private String name;
Private Map<Integer,Double> marks = new HashMap<Integer,Double>();
public Person(String name) { this.name = name; }
public void setMark(int year, double mark) {
this.marks.put(year,mark);
}
public void getMark(int year) {
// return zero if there's no mark for the requested year
return this.marks.containsKey(year) ? this.marks.get(year) : 0;
}
}
Then write a Comparator<Person>
public PersonComparatorOnMarkDescending implements Comparator<Person>
{
private int yearToCompare;
public PersonComparator(int yearToCompare) {
this.yearToCompare = yearToCompare;
}
public compare(Person p1, Person p2)
{
Integer p1Mark = p1.getMark(yearToCompare);
Integer p2Mark = p2.getMark(yearToCompare);
return p2.compareTo(p1);
}
}
You can then define a List<Person> or a Person[] array and use the sorting methods available in java.util. Instantiate the comparator with, for instance:
Comparator<Person> comp = new PersonComparatorOnMarkDescending(2012);
This approach lets you sort the collection on any year's marks.