/* package whatever; // don't place package name! */
import java.util.* ;
import java.lang.* ;
import java.io.* ;
import java.util.ArrayList ;
import java.util.List ;
import java.util.Map ;
import java.util.Objects ;
import java.util.function.Function ;
import java.util.stream.Collectors ;
import java.util.stream.Stream ;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
{
List
< Student
> list
= new ArrayList
<> ( List .
of ( new Student
( 1 ,
new ArrayList
<> ( List .
of ( new Marks
( 1 ,
10 ) ,
new Marks
( 2 ,
10 ) ) ) ) ,
new Student
( 1 ,
new ArrayList
<> ( List .
of ( new Marks
( 1 ,
15 ) ,
new Marks
( 3 ,
10 ) ) ) ) ,
new Student
( 2 ,
new ArrayList
<> ( List .
of ( new Marks
( 1 ,
5 ) ,
new Marks
( 2 ,
10 ) ) ) ) ,
new Student
( 2 ,
new ArrayList
<> ( List .
of ( new Marks
( 2 ,
5 ) ,
new Marks
( 3 ,
10 ) ) ) ) ) ) ;
//Temporary map
Map
< Integer , Student
> mapTemp
= list.
stream ( ) .collect ( Collectors.toMap ( Student:: getStudentId, //grouping by student id
Function.identity ( ) , //setting as value the student
( s1, s2) -> new Student( s1.getStudentId ( ) , new ArrayList<> ( //Creating a new Student whose list of marks is given by the merged marks of the two colliding students
Stream.concat ( s1.getMarkList ( ) .stream ( ) , s2.getMarkList ( ) .stream ( ) ) //Chaining the two lists of marks into a single stream
.collect ( Collectors.toMap ( Marks:: getSubjectId, //Grouping by the marks by the subject id
Function.identity ( ) , //Setting as value the mark
( m1, m2) -> new Marks( m1.getSubjectId ( ) , m1.getMark ( ) + m2.getMark ( ) ) ) ) //Handling the colliding marks by summing them together
.values ( ) ) ) ) //Retrieving the collection of merged marks
) ;
//Result list with the merged students
}
}
class Student {
private int studentId;
private List< Marks> markList = new ArrayList<> ( ) ;
public Student( int studentId, List< Marks> markList) {
this .studentId = studentId;
this .markList = markList;
}
public int getStudentId( ) {
return studentId;
}
public List< Marks> getMarkList( ) {
return markList;
}
@Override
public boolean equals
( Object o
) { if ( this == o) return true ;
if ( o == null || getClass( ) != o.getClass ( ) ) return false ;
Student student = ( Student) o;
return studentId == student.studentId ;
}
@Override
public int hashCode( ) {
return Objects.hash ( studentId) ;
}
@Override
return String .
format ( "[%d - %s]" , studentId, markList
) ; }
}
class Marks {
this .subjectId = subjectId;
this .mark = mark;
}
return subjectId;
}
return mark;
}
public void setSubjectId
( Integer subjectId
) { this .subjectId = subjectId;
}
public void setMark
( Integer mark
) { this .mark = mark;
}
@Override
public boolean equals
( Object o
) { if ( this == o) return true ;
if ( o == null || getClass( ) != o.getClass ( ) ) return false ;
Marks marks = ( Marks) o;
return Objects.equals ( subjectId, marks.subjectId ) ;
}
@Override
public int hashCode( ) {
return Objects.hash ( subjectId) ;
}
@Override
return String .
format ( "[%d - %d]" , subjectId, mark
) ; }
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlMaXN0OwppbXBvcnQgamF2YS51dGlsLkxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuTWFwOwppbXBvcnQgamF2YS51dGlsLk9iamVjdHM7CmltcG9ydCBqYXZhLnV0aWwuZnVuY3Rpb24uRnVuY3Rpb247CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLkNvbGxlY3RvcnM7CmltcG9ydCBqYXZhLnV0aWwuc3RyZWFtLlN0cmVhbTsKCi8qIE5hbWUgb2YgdGhlIGNsYXNzIGhhcyB0byBiZSAiTWFpbiIgb25seSBpZiB0aGUgY2xhc3MgaXMgcHVibGljLiAqLwpjbGFzcyBJZGVvbmUKewoJcHVibGljIHN0YXRpYyB2b2lkIG1haW4gKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBqYXZhLmxhbmcuRXhjZXB0aW9uCgl7CgkJTGlzdDxTdHVkZW50PiBsaXN0ID0gbmV3IEFycmF5TGlzdDw+KExpc3Qub2YoCiAgICAgICAgICAgICAgICBuZXcgU3R1ZGVudCgxLCBuZXcgQXJyYXlMaXN0PD4oTGlzdC5vZihuZXcgTWFya3MoMSwgMTApLCBuZXcgTWFya3MoMiwgMTApKSkpLAogICAgICAgICAgICAgICAgbmV3IFN0dWRlbnQoMSwgbmV3IEFycmF5TGlzdDw+KExpc3Qub2YobmV3IE1hcmtzKDEsIDE1KSwgbmV3IE1hcmtzKDMsIDEwKSkpKSwKICAgICAgICAgICAgICAgIG5ldyBTdHVkZW50KDIsIG5ldyBBcnJheUxpc3Q8PihMaXN0Lm9mKG5ldyBNYXJrcygxLCA1KSwgbmV3IE1hcmtzKDIsIDEwKSkpKSwKICAgICAgICAgICAgICAgIG5ldyBTdHVkZW50KDIsIG5ldyBBcnJheUxpc3Q8PihMaXN0Lm9mKG5ldyBNYXJrcygyLCA1KSwgbmV3IE1hcmtzKDMsIDEwKSkpKQogICAgICAgICkpOwoKICAgICAgICAvL1RlbXBvcmFyeSBtYXAKICAgICAgICBNYXA8SW50ZWdlciwgU3R1ZGVudD4gbWFwVGVtcCA9IGxpc3Quc3RyZWFtKCkKICAgICAgICAgICAgICAgIC5jb2xsZWN0KENvbGxlY3RvcnMudG9NYXAoU3R1ZGVudDo6Z2V0U3R1ZGVudElkLCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL2dyb3VwaW5nIGJ5IHN0dWRlbnQgaWQKICAgICAgICAgICAgICAgICAgICAgICAgRnVuY3Rpb24uaWRlbnRpdHkoKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL3NldHRpbmcgYXMgdmFsdWUgdGhlIHN0dWRlbnQKICAgICAgICAgICAgICAgICAgICAgICAgKHMxLCBzMikgLT4gbmV3IFN0dWRlbnQoczEuZ2V0U3R1ZGVudElkKCksIG5ldyBBcnJheUxpc3Q8PiggICAgICAgICAgICAgICAgICAgICAvL0NyZWF0aW5nIGEgbmV3IFN0dWRlbnQgd2hvc2UgbGlzdCBvZiBtYXJrcyBpcyBnaXZlbiBieSB0aGUgbWVyZ2VkIG1hcmtzIG9mIHRoZSB0d28gY29sbGlkaW5nIHN0dWRlbnRzCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgU3RyZWFtLmNvbmNhdChzMS5nZXRNYXJrTGlzdCgpLnN0cmVhbSgpLCBzMi5nZXRNYXJrTGlzdCgpLnN0cmVhbSgpKSAgICAgLy9DaGFpbmluZyB0aGUgdHdvIGxpc3RzIG9mIG1hcmtzIGludG8gYSBzaW5nbGUgc3RyZWFtCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAuY29sbGVjdChDb2xsZWN0b3JzLnRvTWFwKE1hcmtzOjpnZXRTdWJqZWN0SWQsICAgICAgICAgICAgICAgICAgLy9Hcm91cGluZyBieSB0aGUgbWFya3MgYnkgdGhlIHN1YmplY3QgaWQKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRnVuY3Rpb24uaWRlbnRpdHkoKSwgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1NldHRpbmcgYXMgdmFsdWUgdGhlIG1hcmsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKG0xLCBtMikgLT4gbmV3IE1hcmtzKG0xLmdldFN1YmplY3RJZCgpLCBtMS5nZXRNYXJrKCkgKyBtMi5nZXRNYXJrKCkpKSkgIC8vSGFuZGxpbmcgdGhlIGNvbGxpZGluZyBtYXJrcyBieSBzdW1taW5nIHRoZW0gdG9nZXRoZXIKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC52YWx1ZXMoKSkpKSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvL1JldHJpZXZpbmcgdGhlIGNvbGxlY3Rpb24gb2YgbWVyZ2VkIG1hcmtzCiAgICAgICAgICAgICAgICApOwoKICAgICAgICAvL1Jlc3VsdCBsaXN0IHdpdGggdGhlIG1lcmdlZCBzdHVkZW50cwogICAgICAgIExpc3QgbGlzdFJlcyA9IG5ldyBBcnJheUxpc3QobWFwVGVtcC52YWx1ZXMoKSk7CiAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKGxpc3RSZXMpOwoJfQp9CgpjbGFzcyBTdHVkZW50IHsKICAgIHByaXZhdGUgaW50IHN0dWRlbnRJZDsKICAgIHByaXZhdGUgTGlzdDxNYXJrcz4gbWFya0xpc3QgPSBuZXcgQXJyYXlMaXN0PD4oKTsKCiAgICBwdWJsaWMgU3R1ZGVudChpbnQgc3R1ZGVudElkLCBMaXN0PE1hcmtzPiBtYXJrTGlzdCkgewogICAgICAgIHRoaXMuc3R1ZGVudElkID0gc3R1ZGVudElkOwogICAgICAgIHRoaXMubWFya0xpc3QgPSBtYXJrTGlzdDsKICAgIH0KCiAgICBwdWJsaWMgaW50IGdldFN0dWRlbnRJZCgpIHsKICAgICAgICByZXR1cm4gc3R1ZGVudElkOwogICAgfQoKICAgIHB1YmxpYyBMaXN0PE1hcmtzPiBnZXRNYXJrTGlzdCgpIHsKICAgICAgICByZXR1cm4gbWFya0xpc3Q7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKICAgICAgICBpZiAodGhpcyA9PSBvKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAobyA9PSBudWxsIHx8IGdldENsYXNzKCkgIT0gby5nZXRDbGFzcygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgU3R1ZGVudCBzdHVkZW50ID0gKFN0dWRlbnQpIG87CiAgICAgICAgcmV0dXJuIHN0dWRlbnRJZCA9PSBzdHVkZW50LnN0dWRlbnRJZDsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgcmV0dXJuIE9iamVjdHMuaGFzaChzdHVkZW50SWQpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiWyVkIC0gJXNdIiwgc3R1ZGVudElkLCBtYXJrTGlzdCk7CiAgICB9Cn0KCmNsYXNzIE1hcmtzIHsKICAgIHByaXZhdGUgSW50ZWdlciBzdWJqZWN0SWQ7CiAgICBwcml2YXRlIEludGVnZXIgbWFyazsKCiAgICBwdWJsaWMgTWFya3MoSW50ZWdlciBzdWJqZWN0SWQsIEludGVnZXIgbWFyaykgewogICAgICAgIHRoaXMuc3ViamVjdElkID0gc3ViamVjdElkOwogICAgICAgIHRoaXMubWFyayA9IG1hcms7CiAgICB9CgogICAgcHVibGljIEludGVnZXIgZ2V0U3ViamVjdElkKCkgewogICAgICAgIHJldHVybiBzdWJqZWN0SWQ7CiAgICB9CgogICAgcHVibGljIEludGVnZXIgZ2V0TWFyaygpIHsKICAgICAgICByZXR1cm4gbWFyazsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRTdWJqZWN0SWQoSW50ZWdlciBzdWJqZWN0SWQpIHsKICAgICAgICB0aGlzLnN1YmplY3RJZCA9IHN1YmplY3RJZDsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBzZXRNYXJrKEludGVnZXIgbWFyaykgewogICAgICAgIHRoaXMubWFyayA9IG1hcms7CiAgICB9CgogICAgQE92ZXJyaWRlCiAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKICAgICAgICBpZiAodGhpcyA9PSBvKSByZXR1cm4gdHJ1ZTsKICAgICAgICBpZiAobyA9PSBudWxsIHx8IGdldENsYXNzKCkgIT0gby5nZXRDbGFzcygpKSByZXR1cm4gZmFsc2U7CiAgICAgICAgTWFya3MgbWFya3MgPSAoTWFya3MpIG87CiAgICAgICAgcmV0dXJuIE9iamVjdHMuZXF1YWxzKHN1YmplY3RJZCwgbWFya3Muc3ViamVjdElkKTsKICAgIH0KCiAgICBAT3ZlcnJpZGUKICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgcmV0dXJuIE9iamVjdHMuaGFzaChzdWJqZWN0SWQpOwogICAgfQoKICAgIEBPdmVycmlkZQogICAgcHVibGljIFN0cmluZyB0b1N0cmluZygpIHsKICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiWyVkIC0gJWRdIiwgc3ViamVjdElkLCBtYXJrKTsKICAgIH0KfQo=