2016-08-02 4 views
3

Ich brauche Ihre Hilfe,Java 8. Gruppe eine Liste von Werten in eine Liste der Bereiche Sammler

In Java 8 mit Collectors groupingBy I Gruppe benötigen eine Liste wie diese

ValueObject {id=1, value=2.0} 
ValueObject {id=2, value=2.0} 
ValueObject {id=3, value=2.0} 
ValueObject {id=4, value=3.0} 
ValueObject {id=5, value=3.0} 
ValueObject {id=6, value=4.0} 
ValueObject {id=7, value=4.0} 
ValueObject {id=8, value=4.0} 
ValueObject {id=9, value=4.0} 
ValueObject {id=10, value=4.0} 

in einer anderen Verwendung eine ähnliche

GroupedObject {from=1, to=3, value=2.0} 
GroupedObject {from=4, to=5, value=3.0} 
GroupedObject {from=6, to=10, value=4.0} 

sind diejenigen, die Definitionen der Objekte ich verwende

public class ValueObject { 

    private int id; 
    private double value; 

    public String getId() { 
    return id; 
    } 

    public float getValue() { 
    return value; 
    } 

    public void setValue(float value) { 
    this.value = value; 
    } 

} 

public class GroupedObject { 

    private int from; 
    private int to; 
    private double value; 

    public int getFrom() { 
     return from; 
    } 

    public void setFrom(int from) { 
     this.from = from; 
    } 

    public int getTo() { 
     return to; 
    } 

    public void setTo(int to) { 
     this.to = to; 
    } 

    public double getValue() { 
     return value; 
    } 

    public void setValue(double value) { 
     this.value = value; 
    } 

} 

Und das ist, wie ich es programmatisch mache.

Dies ist das Gerät zu testen

public class ServiceTest { 

    Service service = new Service(); 

    @Test 
    public void testgGoupToRange() { 

     List entryList = new ArrayList<>(); 

     entryList.add(new ValueObject(1, 2.0)); 
     entryList.add(new ValueObject(2, 2.0)); 
     entryList.add(new ValueObject(3, 2.0)); 
     entryList.add(new ValueObject(4, 3.0)); 
     entryList.add(new ValueObject(5, 3.0)); 
     entryList.add(new ValueObject(6, 4.0)); 
     entryList.add(new ValueObject(7, 4.0)); 
     entryList.add(new ValueObject(8, 4.0)); 
     entryList.add(new ValueObject(9, 4.0)); 
     entryList.add(new ValueObject(10, 4.0)); 

     List responseList = service.groupToRange(entryList); 

     responseList.forEach(obj-> System.out.println(obj.toString())); 

     assertNotNull(responseList); 
     assertEquals(3, responseList.size()); 

    } 

} 

ich einen Weg havn't es Java 8 und Sammler

+1

Ja, Sie Software schreiben, es zu tun. Bitte investieren Sie die geringste Anstrengung, bevor Sie Ihr Problem an andere weitergeben, um es für Sie zu lösen. –

+0

Entschuldigung, ich habe es schon getan. Aber ich möchte wissen, ob es eine Möglichkeit gibt, CollectorsBy zu verwenden. –

+1

Die angegebene ValueObject-Definition wird nicht kompiliert. – GuiSim

Antwort

2

Hier ist, was ich kam mit

List<ValueObject> values = Arrays.asList(new ValueObject(1, 2.0), 
             new ValueObject(2, 2.0), 
             new ValueObject(3, 3.0), 
             new ValueObject(4, 4.0), 
             new ValueObject(5, 4.0), 
             new ValueObject(6, 4.0)); 
Map<Double, IntSummaryStatistics> groupedValues = values.stream() 
                 .collect(Collectors.groupingBy(ValueObject::getValue, 
                         Collectors.summarizingInt(ValueObject::getId))); 

List<GroupedObject> groupedObjects = groupedValues.entrySet() 
                .stream() 
                .map(groupedValue -> new GroupedObject(groupedValue.getValue().getMin(), 
                        groupedValue.getValue().getMax(), 
                        groupedValue.getKey())) 
                .collect(Collectors.toList()); 
System.out.println(groupedObjects); 
Whit tun gefunden

Ich bin ziemlich sicher, dass es einen Weg gibt, den Vermittler Map<Double, IntSummaryStatistics zu vermeiden, aber ich habe es nicht herausgefunden y et. Wird aktualisiert, wenn ich es tue.

EDIT: Siehe @ Tunaki die Antwort für eine 1-Pass-Antwort.

Dies ist die Ausgabe

[GroupedObject{from=4, to=6, value=4.0}, GroupedObject{from=1, to=2, value=2.0}, GroupedObject{from=3, to=3, value=3.0}] 
+2

Es gibt einen Weg mit nur 1 Pass, aber es ist nicht so einfach (siehe meine Antwort auf eine verwandte Frage) (http://stackoverflow.com/a/36445457/1743880)). Am besten wäre es, dabei zu bleiben. – Tunaki

+1

Wirklich danke, das ist ein wirklich guter Ansatz von dem, was ich suchte. Ich habe einen Sortierausdruck hinzugefügt, um die letzte Gruppe der Reihe nach abzurufen. .sortiert (Comparator.comparing (GroupedObject :: getFrom)) –

Verwandte Themen