Initial prototype for BiStream

Rémi Forax forax at univ-mlv.fr
Wed Apr 25 15:36:12 PDT 2012


Hi Peter,
The original implementation of IdentityHashMap was based on the same
idea, reusing Map.Entry implementation, and it didn't work well.

Full story here:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6232484

Rémi


On 04/26/2012 12:25 AM, Peter Levart wrote:
> On Wednesday, April 18, 2012 03:39:28 PM Mike Duigou wrote:
>> There's a big question lurking in the implementation involving
>> boxing/unboxing of BiValue<L,R>  as used by the BiBlock, BiMapper and
>> Predicate.
> I don't know if this is a good idea, but pragmatic approach could be to re-use the intermediate BiValues
> and control manually if you need BiValue(s) by reference or just momentarily for extracting the components
> (i.e. whether the reference to BiValue "escapes" the iteration step or not).
>
> For example:
>
> public abstract class BiValueStream<T, U>  implements Iterable<BiValue<T, U>>
> {
>     private boolean reuseResult = true;
>
>     private static class BiVal<T, U>  implements BiValue<T, U>
>     {
>        private T left;
>        private U right;
>
>        @Override
>        public T left()
>        {
>           return left;
>        }
>
>        @Override
>        public U right()
>        {
>           return right;
>        }
>     }
>
>     <V>  BiValueStream<T, V>  map(final BiMapper<T, U, V>  mapper)
>     {
>        return new BiValueStream<T, V>()
>        {
>           @Override
>           public Iterator<BiValue<T, V>>  iterator()
>           {
>              final Iterator<BiValue<T, U>>  source = BiValueStream.this.iterator();
>
>              return new Iterator<BiValue<T, V>>()
>              {
>                 @Override
>                 public boolean hasNext()
>                 {
>                    return source.hasNext();
>                 }
>
>                 private BiVal<T, V>  reusableResult = reuseResult ? new BiVal<T, V>() : null;
>
>                 @Override
>                 public BiValue<T, V>  next()
>                 {
>                    BiValue<T, U>  next = source.next();
>                    BiVal<T, V>  result = reuseResult ? reusableResult : new BiVal<T, V>();
>                    result.left = next.left();
>                    result.right = mapper.map(next.left(), next.right());
>                    return result;
>                 }
>              };
>           }
>        };
>     }
>
>     public BiValueStream<T, U>  reuseResult(boolean reuseResult)
>     {
>        this.reuseResult = reuseResult;
>        return this;
>     }
> }
>
>
> // an example where BiVal is resused:
>
> BiValueStream<String, String>  keyVals = ...;
> Map<String, Integer>  keyValLengths = new HashMap<>();
>
> for (BiValue<String, Integer>  keyValLength : keyVals.map((key, val) ->  key.length() + val.length()))
> {
>     keyValLengths.put(keyValLength.left(), keyValLength.right());
> }
>
> // and where it is not:
>
> List<BiValue<String, Integer>>  keyValLengthList = new ArrayList<>();
>
> for (BiValue<String, Integer>  keyValLength : keyVals.map((key, val) ->  key.length() + val.length()).reuseResult(false))
> {
>     keyValLengthList.add(keyValLength);
> }
>
>
> ...usually, when you chain transformations, you don't need intermediate BiValues by reference, just the components. Only at the end you may need them.
>
>
> Regards,
> Peter
>
>



More information about the lambda-dev mailing list