Function Object in Java

后端 未结 5 759
醉话见心
醉话见心 2021-02-03 11:32

I wanna implement a javascript like method in java , is this possible ?

Say , I have a Person class :

public class Person {
 private String name ;
 priva         


        
相关标签:
5条回答
  • 2021-02-03 12:07

    You can do it with an interface and an anonymous inner class implementing it, like

    Person p1 = new Person("Jenny",20);
    Person p2 = new Person("Kate",22);
    List<Person> pList = Arrays.asList(p1, p2);
    
    interface Operation {
      abstract void execute(Person p);
    }
    
    public void modList(List<Person> list, Operation op) {
      for (Person p : list)
        op.execute(p);
    }
    
    modList(pList, new Operation {
      public void execute(Person p) { p.setAge(p.getAge() + 1)};
    });
    

    Note that with varargs in Java5, the call to Arrays.asList can be simplified as shown above.

    Update: A generified version of the above:

    interface Operation<E> {
      abstract void execute(E elem);
    }
    
    public <E> void modList(List<? extends E> list, Operation<E> op) {
      for (E elem : list)
        op.execute(elem);
    }
    
    modList(pList, new Operation<Person>() {
        public void execute(Person p) { p.setAge(p.getAge() + 1); }
    });
    

    Note that with the above definition of modList, you can execute an Operation<Person> on e.g. a List<Student> too (provided Student is a subclass of Person). A plain List<E> parameter type would not allow this.

    0 讨论(0)
  • 2021-02-03 12:10

    Yes, this is easy in a functional programming language.. in Java it's a little more complex but you can work out something like this, using also generics types when possible:

    public class TestCase {
        static interface Transformable {};
    
        static class Person implements Transformable {
            Person(String name, int age) {
                this.name = name;
                this.age = age;
            }
    
            public String name;
            public int age;
        }
    
        static interface Modifier<T extends Transformable> {
            void modify(Transformable object);
        }
    
        static class AgeIncrementer implements Modifier<Person> {
            public void modify(Transformable p) {
                ++((Person)p).age;
            }
        }
    
        static void applyOnList(List<? extends Transformable> objects, Modifier<? extends Transformable> modifier) {    
            for (Transformable o : objects) {
                modifier.modify(o);
            }
        }
    
        public static void main(String[] args) {
            ArrayList<Person> l = new ArrayList<Person>();
            l.add(new Person("John", 10));
            l.add(new Person("Paul", 22));
            l.add(new Person("Frank", 35));
    
            applyOnList(l, new AgeIncrementer());
    
            for (Person p : l)
                System.out.println(p.age);
        }
    }
    
    0 讨论(0)
  • 2021-02-03 12:15

    Look at the google collections library. Look at the transform methods on Iterators and Iterables. That should be able to get you what you want.

    0 讨论(0)
  • 2021-02-03 12:16

    Take a look at the lambdaj project. Here is an example from the project home page:

    List<Person> personInFamily = asList(new Person("Domenico"), new Person("Mario"), new Person("Irma"));
    forEach(personInFamily).setLastName("Fusco");
    
    0 讨论(0)
  • 2021-02-03 12:25
    import java.util.Arrays;
    import java.util.List;
    import java.util.function.Function;
    import java.util.stream.Collectors;
    
    public class FuntionAsParameter {
    
    
        public static void main(final String[] args) {
    
            Person p1 = new Person("Jenny", 20);
            Person p2 = new Person("Kate", 22);
    
            List<Person> pList = Arrays.asList(new Person[]{p1, p2});
    
            Function<List<Person>, List<Person>> theFunction = Function.<List<Person>>identity()
                .andThen(personList -> personList
                    .stream()
                    .map(person -> new Person(person.getName(), person.getAge() + 1))
                    .collect(Collectors.toList()));
    
            // You can use this directly
            List<Person> directly = theFunction.apply(pList);
            directly.forEach(person -> System.out.println(person));
    
            // Or use it as an input parameter
            List<Person> toMethod = modList(pList, theFunction);
            toMethod.forEach(person -> System.out.println(person));
    
            // Or you might prefer this way
            List<Person> thirdWay = modList(pList,
                    (list) -> list.stream()
                            .map(person -> new Person(person.getName(), person.getAge() + 1))
                            .collect(Collectors.toList())
            );
            thirdWay.forEach(person -> System.out.println(person));
        }
    
        private static List<Person> modList(List<Person> personList, Function<List<Person>, List<Person>> theFunction) {
            return theFunction.apply(personList);
        }
    
    
    }
    
    class Person {
    
        private String name;
        private int age;
    
        public Person(final String name, final int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public int getAge() {
            return age;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
        }
    }
    
    0 讨论(0)
提交回复
热议问题