J
J
Jake Taylor2021-06-07 16:14:12
Java
Jake Taylor, 2021-06-07 16:14:12

How to assemble a sorted object using streams in Java?

There is a TextItem object that contains an ArrayList. This ArrayList contains many TextItems and so on (created using the Composite template).
With streams, I want to sort nested objects like this:

component.getChildComponents().stream()
                    .sorted(Comparator.comparingInt(TextComponent::getCountChildElements))
                    .collect( // ???


I just don't understand how to assemble it back into an object of type TextItem .

Here is the TextItem itself:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class TextItem implements TextComponent {
    private Iterator<TextComponent> iterator;
    private TypeComponent type;
    private final List<TextComponent> childComponents;

    public TextItem(TypeComponent typeComponent) {
        this.type = typeComponent;
        childComponents = new ArrayList<>();
    }

    @Override
    public void add(TextComponent textComponent) {
        childComponents.add(textComponent);
    }

    @Override
    public void remove(TextComponent textComponent) {
        childComponents.remove(textComponent);
    }

    @Override
    public TypeComponent getComponentType() {
        return this.type;
    }

    @Override
    public TextComponent getChild(int index) {
        return childComponents.get(index);
    }

    @Override
    public int getCountChildElements() {
        return childComponents.size();
    }

    @Override
    public int getCountAllElements() {
        return childComponents.stream()
                .mapToInt(TextComponent::getCountAllElements)
                .sum();
    }

    @Override
    public Iterator<TextComponent> createIterator() {
        if(iterator == null) {
            iterator = new CompositeIterator(childComponents.iterator());
        }

        return iterator;
    }

    @Override
    public List<TextComponent> getChildComponents() {
        return childComponents;
    }

    @Override
    public String toString() {
        StringBuilder msg = new StringBuilder();

        for (TextComponent component : childComponents) {
            msg.append(component.toString());
        }

        return msg.toString();
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }

        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        TextItem that = (TextItem) o;

        return type == that.type &&
                childComponents.equals(that.childComponents);
    }

    @Override
    public int hashCode() {
        int result = 17;

        result = 31 * result + (type != null ? type.hashCode() : 0);
        result = 31 * result + childComponents.hashCode();

        return result;
    }
}

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
Dmitry Roo, 2021-06-07
@n199a

var result  =  component.getChildComponents().stream()
                    .sorted(Comparator.comparingInt(TextComponent::getCountChildElements))
                    .collect(Collectors.toList());
component.getChildComponents().clear();
component.getChildComponents().addAll(result);

It is better to add one more method to the TextItem and pass the result to it (remove only final from ChildComponents).
public void setChildComponents(List<TextComponent> childComponents) {
       this.childComponents = childComponents;
    }

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question