Streams

I tried to use lambdas to swap elements in the char[] array. Does this mean that I am trying to change the stream while it is streaming ? This code is from http://www.cs.uofs.edu/~mccloske/courses/cmps144/invariants_lec.html but this question is unrelated to those concepts.

If that is a problem then a new stream will do. How should this be done ? I am not looking for a Comparator. I would like to work with this code as it is without using any API but lambdas.

I am printing using lambdas in this code now.

public class DutchNationalFlag {

    private static final int N = 10;

    private static char[] flags = new char[]{'R','B','B','R','R','B','B','R','R','B'};

    public static void main( String... argv){

        new String(flags).chars().mapToObj(i -> (char)i).forEach(System.out::println);

        int m = 0,  k = 0;
        while (m != N)  {
            if (flags[m] == 'B') { }
            else {
                swap(flags,k,m); 
                k = k+1;
            }
            m = m+1;
        } 
        new String(flags).chars().mapToObj(i -> (char)i).forEach(System.out::println);
    }

    private static void swap(char[] flags, int k, int m) {

        char temp = flags[k];
        flags[k] = flags[m];
        flags[m] =  temp;

    }

}

Possible Solution 1:

This doesn’t do exactly what the original code does. It doesn’t swap and doesn’t advance k which is the boundary between ‘B’ and ‘R’.But it produces the result.

    Stream<Character> stream1 = 
    IntStream.range(0, flags.length).mapToObj(i -> (char)flags[i]);

    Stream<Character> stream2 = 
    IntStream.range(0, flags.length).mapToObj(i -> (char)flags[i]);


    Stream.concat(stream2.filter(x-> (x == 'B')), stream1.filter( y->(y == 'R')  )).forEach(System.out::println);

6 Responses to Streams

  1. Simon says:

    new String(flags).chars().sorted().forEach(i -> System.out.println((char)i));

  2. Yes. I was trying to do this by swapping without using a API call to learn how it is done using only streams. Your code works too.

  3. Simon says:

    It did highlight to me that from an IntStream I wouldn’t be able to sort it in descending order without using boxed() so that I could pass a Comparator. IntStream probably needs a new method “sortedReversed”.

  4. Simon says:

    I think that Streams are a bit higher level than swapping individual elements. Streams is more about what, rather than how. A lot of the API has been designed so you can throw parallel() into the chain and things will mostly still work.

    The algorithm for swapping accesses elements in order and then backtracks (directly accesses) to swap old elements. A Stream is closer to an Iterator in that it doesn’t assume you can go backwards, but also it isn’t, in that it could choose to not do things in order at all (in the case of parallel it will usually use Fork/Join and approach the task in a divide and conquer way),

  5. I thought ‘zip’ could help. So just as an academic exercise one could create two streams one lagging behind the other by one element. A new stream could contain the result. I tried this but my lambda knowledge wasn’t enough. FJ can still be used in this case.

  6. Simon says:

    Streams tries to be as lazy as possible: it won’t necessarily zip them all up and then apply the next operation on them afterwards. It could try to evaluate the entire chain in parallel and so it would want to chop up the zip operation as well and this doesn’t work as each part can’t be evaluated until the previous has been.

    customers.stream.mapToInt(Customer::getSalary).sum();
    will flow more like (in the serial case):

    int sum = 0;
    for (Customer c : customers) {
    int salary = c.getSalary();
    sum += salary
    }

    rather than:

    List salaries = List();
    for (Customer c : customers) { salaries.add(c.getSalary(); } // Operation 1
    int sum = 0;
    for(int salary : salaries) { sum += salary; } // Operation 2

    If you are interested (my memory is a little fuzzy about it now), you might like :
    http://www.infoq.com/presentations/java-streams-scala-parallel-collections

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: