kiaora
kiaora

Reputation: 79

Generic Mapping in Java

I would like to write a static, generic method map, which gets two arguments: The first argument is an object that implements the interface public interface Function<X,Y> { public Y apply(X x); }; the second argument has the type LinkedList . The method returns a linked list of elements from Y. Each element of the result list was calculated by applying the first argument to an element of the argument list; the order corresponds to the argument list.

Example:        

Function <Integer, Boolean> even = new Even ();
System.out.println (map (even, xs));

For the list xs = [72, 9, 21, 174, 6, 93], in this example [true, false, false, true, true, false] is printed, whereby the class Even implements a function, which only true returns for even arguments.


So far I have managed to get it working for the specific types (Integer, Boolean) but I have trouble turning this solution into a generic one.

I thought I could just replace Boolean and Integer with X and Y but this didn't work.

My code so far:

import java.util.LinkedList;

public class Map<X,Y>{

    private X xgen;
    private Y ygen;


    private static LinkedList<Y> map(Function<X, Y> obj, LinkedList<X> xs) {
        LinkedList<Y> res = new LinkedList<>();
        for (X x:xs){ //Lambda also possible
            res.add(obj.apply(x));
        }
        return res;
    }


    public static void main(String[] args) {
        Function<Integer,Boolean> even = new Even();
        LinkedList<Integer> xs= new LinkedList<>();
        xs.add(72);
        xs.add(9);
        xs.add(21);
        xs.add(174);
        xs.add(6);
        xs.add(93);
        System.out.println(xs);
        System.out.println(map(even,xs));

    }
}

And for testing purposes I also wrote the Even class:

public class Even implements Function<X,Y> {

    Even(){}

    @Override
    public Y apply(X integer) {
        return (integer % 2) == 0;
    }
}

Any ideas, tips or hints are greatly appreciated.



EDIT: AS @user202729 pointed out, I didn't state the problem with my code:

For Map.java

Error:(9, 47) java: non-static type variable X cannot be referenced from a static context
Error:(9, 50) java: non-static type variable Y cannot be referenced from a static context
Error:(9, 69) java: non-static type variable X cannot be referenced from a static context
Error:(9, 31) java: non-static type variable Y cannot be referenced from a static context
Error:(10, 20) java: non-static type variable Y cannot be referenced from a static context
Error:(11, 14) java: non-static type variable X cannot be referenced from a static context

For Even.java

Error:(1, 39) java: cannot find symbol
  symbol: class X
Error:(1, 41) java: cannot find symbol
  symbol: class Y
Error:(6, 20) java: cannot find symbol
  symbol:   class X
  location: class Even
Error:(6, 12) java: cannot find symbol
  symbol:   class Y
  location: class Even

Upvotes: 2

Views: 142

Answers (2)

Amit Bera
Amit Bera

Reputation: 7315

In Java-8 you can do it without creating your own implementation.

xs.stream().map(e -> e%2==0).collect(Collectors.toList());

The above statement will do the same task.

Upvotes: 0

Eran
Eran

Reputation: 393781

First of all, your Even class expects X to be Integer and Y to be Boolean, which means it should be defined as:

class Even implements Function<Integer,Boolean> {
    Even(){}

    @Override
    public Boolean apply(Integer integer) {
        return (integer % 2) == 0;
    }
}

Second of all, if you want a static method to use generic type parameters, it must define its own parameters:

private static <X,Y> LinkedList<Y> map(Function<X, Y> obj, LinkedList<X> xs) {
    LinkedList<Y> res = new LinkedList<>();
    for (X x:xs){ //Lambda also possible
        res.add(obj.apply(x));
    }
    return res;
}

A static method cannot access the generic type parameters of the class level.

Upvotes: 3

Related Questions