0

I have 3 ways to swap 2 variables (basically 3 different algorithms). Since you can't pass a method as a parameter in Java, I thought this would be a good time to use lambda expressions.

chooseSwapMethod(int selection) {
    if(selection == 1) {
        functionThatUsesSwap(
            (int[] arr, int x, int y) -> {
                int holder = arr[x];
                arr[x] = arr[y];
                arr[y] = holder;
        });
    }
    else if(selection == 2)
    {
        functionThatUsesSwap(
            (int[] arr, int x, int y) -> {
                arr[x] -= arr[y];
                arr[y] = arr[x]-arr[y];
                arr[x] -= arr[y];
        });
    }
    else if(selection == 3) {
                functionThatUsesSwap(
            (int[] arr, int x, int y) -> {
                arr[x] = arr[x]^arr[y];
                arr[y] = arr[y]^arr[x];
                arr[x] = arr[x]^arr[y];
        });
    }
    else {
        throw new IllegalArgumentEarr[x]ception();
    }
}

but in the method functionThatUsesSwap how do you actually use the swap? Am I not understanding lambda expressions clearly? For example

public void functionThatUsesSwap(Swaper s)
{
    int[] someArr = {1, 2};
    s.doSwap(someArr, 0, 1);//this is where I’m stuck
    System.out.println(“a: “+someArr[0]+” b: “+someArr[1]);//this should print out a: 2 b: 1
}
Celeritas
  • 14,489
  • 36
  • 113
  • 194
  • 1
    Did you define the Swaper interface? Can you include it in the question? In addition, your previous revision with the array has more chances of working, since `s.doSwap(a, b)` can't change the values of a and b (since Java passes parameters to methods by value), so they won't be swapped. – Eran Jul 16 '14 at 23:15
  • @Eran well, I thought the point of lambda expressions is to get ride of the need for interfaces. I have implemented the swap interface with the 3 algorithms but now I'm working on getting rid of them. – Celeritas Jul 16 '14 at 23:19
  • What's the definition of the `Swaper` type which is used as parameter in `functionThatUsesSwap`? – Eran Jul 16 '14 at 23:21
  • The lambda expressions implement the interface, but you still have to define a Swaper functional interface with a single method doSwap that accepts the parameters you wish to pass to it. Alternatelly, you can use predefined functional interfaces. – Eran Jul 16 '14 at 23:24
  • @Eran that's my question to you :) Given the lambda expression what should go in place instead of `Swaper`? – Celeritas Jul 16 '14 at 23:24
  • 1
    Just making sure: swapping is just example, right, since your methods only swap their local variables, not actual variables passed to method (this would be impossible since java is pass-by-value). BTW there is also 4rd option `a=b+0*(b=a)`. – Pshemo Jul 16 '14 at 23:28
  • @Pshemo this is all just an example – Celeritas Jul 16 '14 at 23:33
  • @Pshemo Wow, yet another item to add to the arsenal of useless knowledge. :-) – Stuart Marks Jul 16 '14 at 23:44

1 Answers1

4

Java is pass by value, that means that in the following:

int a = 5;
int b = 6;
swap(a,b);
System.out.println(a+" "+b);

There is no way for the function swap to change value of a or b and the result will always be 5 6.

What you can do is:

  1. pass and arrays of 2 numbers into the swap method, and swap numbers inside that array.
  2. make a class to hold 2 numbers and pass that.

Going with possibility 2:

class Pair {
    int a, b;
}

@FunctionalInterface
interface Swapper {
    void swap(Pair p);
}

void main() {
    Pair p = new Pair();
    p.a = 5;
    p.b = 6;
    Swapper swapper = (v -> {
        v.a ^= v.b;
        v.b ^= v.a;
        v.a ^= v.b;
    });
    swapper.swap(p);
    System.out.println(p.a + " " + p.b);
}

Result: 6 5. Note that your claim that you can't pass a method as a parameter in Java isn't entirely true, since you can pass interfaces instead.

EDIT:

There is yet another approach (I haven't thought of this earlier because Interger class is immutable). You can create a mutable (= changable) object vrapper for integer value, something like:

class IntVrapper {
    public int value;
}

Then your swap method could swap data between those two objects.

kajacx
  • 12,361
  • 5
  • 43
  • 70
  • So the point of the lambda expression is now you don't have to implement the interface in a separate class (and that's seen as a save of work)? – Celeritas Jul 16 '14 at 23:36
  • primitives are pass by value, objects are pass by reference; this is what confuses people when they first start using Java. The AtomicInteger class can be used when trying to pass an integer by reference. – LINEMAN78 Jul 16 '14 at 23:38
  • 3
    Well, objects are references, and that reference is passed as value, not as reference, more here [link](http://stackoverflow.com/questions/40480/is-java-pass-by-reference-or-pass-by-value) – kajacx Jul 16 '14 at 23:40
  • @LINEMAN78 actually everything is passed by value in Java. However the reference to objects are passed by value. In any case, how does this pertain to the discussion at hand? – Celeritas Jul 16 '14 at 23:40
  • 4
    @LINEMAN78 "*primitives are pass by value, objects are pass by reference*" nooooooo, no no. Everything is pass-by-value in Java. You don't pass reference, you pass value of reference (instance it holds) to local copy of that reference (method argument). – Pshemo Jul 16 '14 at 23:40
  • @Celeritas Labmda expressions were introduced to eliminate anonymous inner classes for simple interface implementation. The swapper above is the same as `new Swapper(){public void swap(Pair v){v.a^=v.b;v.b^=v.a;v.a^=v.b;}}` – LINEMAN78 Jul 16 '14 at 23:42
  • 3
    You can skip the custom Swapper interface by reusing the existing java.function.Consumer. – isnot2bad Jul 16 '14 at 23:55
  • Why is it in lambda expressions all of a sudden you don't need to specify data types? Isn't Java strongly typed? – Celeritas Jul 17 '14 at 23:26
  • @Celeritas: Java still is srong-type. And you *can* specifi data types when using lambda. The important part is that you don't *have to* since lambda is only for interfaces with one abstract method, then it is clear what method you are using, so the data types are imported from that method and you don't have to write them. – kajacx Jul 18 '14 at 11:30
  • Ok thanks. Just one other thing. Isn't the name abstract method misleading since we're talking about an interface, not an abstract class? – Celeritas Jul 18 '14 at 17:29
  • Yea, in interface, every method is abstract, so you don't have to use the `abstract` keyword. – kajacx Jul 18 '14 at 19:43
  • The terms "**pass-by-value**" semantics and "**pass-by-reference**" semantics have very precise definitions, and they're often _horribly abused when folks talk about Java_. See: http://www.javadude.com/articles/passbyvalue.htm – thomson Oct 12 '18 at 05:11