2

I have the following classes:

class Data {
        String systemId;
        String fileName;
        int x;
        int y;

        Data(String systemId, String fileName, int x, int y) {
            this.systemId = systemId;
            this.fileName = fileName;
            this.x = x;
            this.y = y;
        }
        public String getSystemId() {
            return systemId;
        }

        public void setSystemId(String systemId) {
            this.systemId = systemId;
        }

        public String getFileName() {
            return fileName;
        }

        public void setFileName(String fileName) {
            this.fileName = fileName;
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getY() {
            return y;
        }

        public void setY(int y) {
            this.y = y;
        }
    }


class Result {
        int x;
        int y;

        Result(int x, int y) {
            this.x = x;
            this.y = y;
        }

        public int getX() {
            return x;
        }

        public void setX(int x) {
            this.x = x;
        }

        public int getY() {
            return y;
        }

        public void setY(int y) {
            this.y = y;
        }
    }

List<Data> dataList = new ArrayList<>();
Data x1 = new Data("n1", "f1", 1, 2);
Data x2 = new Data("n1", "f1", 3, 4);
Data x3 = new Data("n1", "f1", 5, 6);
Data x4 = new Data("n1", "f2", 7, 8);
Data x5 = new Data("n2", "f1", 9, 10);
Data x6 = new Data("n2", "f2", 11, 12);
Data x7 = new Data("n3", "f1", 13, 14);
Data x8 = new Data("n4", "f1", 15, 16);

dataList.add(x1);dataList.add(x2);dataList.add(x3);dataList.add(x4);dataList.add(x5);dataList.add(x6);dataList.add(x7);dataList.add(x8);

I want to use Java streams to create a Map<String, List<Result>> out of the given input list. Also, the list values needs to be sorted in ascending order according to fields (x and y)

I need the output map to be as follows:

{"n1:f1" : [(1, 2), (3, 4), (5, 6)]
 "n1:f2" : [(7, 8)]
 "n2:f1" : [(9, 10)]
 "n2:f2" : [(11, 12)]
 "n3:f1" : [(13, 14)]
 "n4:f1" : [(15, 16)]
}

The key for the map is the combination of systemid and filename concatenated by colon. I tried grouping by the combination of systemid and filename but was not able to proceed with that approach.

0

1 Answer 1

6

You can use groupingBy collector with mapping downstream as :

Map<String, List<Result>> map = data.stream()
        .collect(Collectors.groupingBy(a -> a.getSystemId() + ":" + a.getFileName()
                , Collectors.mapping(a -> new Result(a.getX(), a.getY()),
                        Collectors.toList())));
Sign up to request clarification or add additional context in comments.

9 Comments

Note: This relies on the uniqueness of the grouping key a -> a.getSystemId() + ":" + a.getFileName() to produce correct results.
Yes, that's true. I used a similar approach using method references instead of a -> a.getSystemId() + ":" + a.getFileName() but it was giving compilation error. Can we achieved this with that? If not, why?
If by achieving you mean being able to use method reference for the creation of the grouping key. You can create util such as String createGroupingKey(Data data) which accepts a type of Data attribute to return the key in the expected format and then reference it as,.groupingBy(UtilClass::createGroupingKey,....
@Abhilash28Abhi that's just not how method references work. A method reference stands for a Function object in this case, not the potential result of the method call. If you cast each method reference, you can concatenate them with a string, but that would still not do what you'd want (try this for example: ((Function<String, ?>) String::format) + ":" + ((Function<String, ?>) String::trim)). Writing it as a lambda expression is the way to go.
@Abhilash28Abhi Simple answer to that could be Data::getSystemId is not a String if you are considering it to be.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.