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