简体   繁体   中英

Java var type inference on generic parameter type

I'm having a merge-Function for a stream collector and trying to make it generical applicable. Since the lambda is accepting var as parameter type and the resulting type is of BinaryOperator, I'm trying to get something like BinaryOperator<?> or similar.

BinaryOperator<InsertYourFavouriteType> rejectNewValueAndWarn = (oldValue, newValue ) -> {
            LOGGER.warn( "Old value already present in map, rejecting to collect new value" );
            LOGGER.warn( "Old value:" + oldValue );
            LOGGER.warn( "New value:" + newValue );
            return oldValue;
        };

This is already pretty generic applicable, but I want to get rid of the explicit type in the generics parameter.

You can't do that directly 1 with a variable, but it is entirely possible using a method:

public final class Rejecter {
    public static <T> T rejectNewValueAndWarn(T oldValue, T newValue) {
        LOGGER.warn("Old value already present in map, rejecting to collect new value");
        LOGGER.warn("Old value:" + oldValue);
        LOGGER.warn("New value:" + newValue);
        return oldValue;
    }
}

Then you can use method references to reference the method directly:

Map<A, B> map = whatever.stream()
    .collect(Collectors.toMap(
        ..., // your key mapper
        ..., // your value mapper
        Rejecter::rejectNewValueAndWarn // the merge function
    ));

1 You could define the generic parameter to be either ? or Object , but then you would need casts for every usage, like (BinaryOperator<SomeType>) rejectNewValueAndWarn , which effectively eliminates the whole purpose of extracting this logic into a common place.

Ok, after the hint with the generics type as type parameter I came up with having a mergefunction defined as follows:

static < K > BinaryOperator< K > mergeFunction()
    {
        BinaryOperator< K > rejectNewValueAndWarn = ( oldValue, newValue ) -> {
            LOGGER.warn( "Old value already present in map, rejecting to collect new value" );
            LOGGER.warn( "Old value:" + oldValue );
            LOGGER.warn( "New value:" + newValue );
            return oldValue;
        };
        return rejectNewValueAndWarn;
    }

blablaList.
            .stream()
            .collect( Collectors.toMap( AbstractDto::getName, Function.identity(), mergeFunction() ) );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM