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