Initial prototype for BiStream

Mike Duigou mike.duigou at oracle.com
Wed Apr 25 17:33:31 PDT 2012


Or, if you are the type of person who likes to be their explanations to be entertaining: 

http://youtu.be/wbp-3BJWsU8?t=10m20s

which was bug:

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6312706

Mike



On Apr 25 2012, at 15:36 , Rémi Forax wrote:

> 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