J'ai la situation suivante:

import com.google.common.collect.ImmutableMap;
import org.junit.Test;

import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Stream;

import static java.util.stream.Collectors.toMap;

public class MapFieldIndexTest {

    List<String> HEADERS = Arrays.asList("D header", "B header", "A header", "C header" );

    @Test
    public void testMapIndex() {

        System.out.println(mapHeaderIndex());

    }

    protected Map<SomeHeaderEnum, Integer> mapHeaderIndex() {
        AtomicInteger index = new AtomicInteger();
        return HEADERS.stream()
                .collect(toMap(
                        SomeHeaderEnum::getFieldByHeader ,
                        s -> index.getAndIncrement(),
                        (oldV, newV)->newV)
                );
    }

    public enum SomeHeaderEnum {

        SOME_A("A header"),
        SOME_B("B header"),
        SOME_C("C header"),
        SOME_D("D header");

        public static final ImmutableMap<String, SomeHeaderEnum> fieldsByNormalizedHeader = Stream.of(values())
                .collect(ImmutableMap.toImmutableMap(e -> e.getHeader().toUpperCase(), Function.identity()));

        private String header;


        private SomeHeaderEnum(String header) {
            this.header = header;
        }

        public String getHeader() {
            return header;
        }

        public static SomeHeaderEnum getFieldByHeader(@NotNull String header) {
            String normalizedHeader = header.trim().toUpperCase();
            if (fieldsByNormalizedHeader.containsKey(normalizedHeader))
                return fieldsByNormalizedHeader.get(normalizedHeader);
            throw new IllegalArgumentException("Header not found: " + header);
        }
    }

    public enum AnotherHeaderEnum {

        ANOTHER_SOME_A("A header"),
        ANOTHER_SOME_B("B header"),
        ANOTHER_SOME_C("C header"),
        ANOTHER_SOME_D("D header");

        public static final ImmutableMap<String, AnotherHeaderEnum> fieldsByNormalizedHeader = Stream.of(values())
                .collect(ImmutableMap.toImmutableMap(e -> e.getHeader().toUpperCase(), Function.identity()));

        private String header;


        private AnotherHeaderEnum(String header) {
            this.header = header;
        }

        public String getHeader() {
            return header;
        }

        public static AnotherHeaderEnum getFieldByHeader(@NotNull String header) {
            String normalizedHeader = header.trim().toUpperCase();
            if (fieldsByNormalizedHeader.containsKey(normalizedHeader))
                return fieldsByNormalizedHeader.get(normalizedHeader);
            throw new IllegalArgumentException("Another Header not found: " + header);
        }
    }
}

Je veux rendre mapHeaderIndex générique afin que je puisse l'utiliser avec les deux Enums.

    protected <T, K> Map<T, Integer> mapHeaderIndex(Function<? super T, ? extends K> keyMapper) {
        AtomicInteger index = new AtomicInteger();
        return HEADERS.stream()
                .collect(toMap(
                        keyMapper,
                        s -> index.getAndIncrement(),
                        (oldV, newV)->newV)
                );
    }

Qu'est-ce que je rate?

0
Flavio Oliva 19 avril 2020 à 13:10

3 réponses

Meilleure réponse

Vous pouvez rendre mapHeaderIndex générique comme ceci:

protected <T> Map<T, Integer> mapHeaderIndex(Function<? super String, ? extends T> stringToKey) {
    AtomicInteger index = new AtomicInteger();
    return HEADERS.stream()
            .collect(toMap(
                    stringToKey,
                    s -> index.getAndIncrement(),
                    (oldV, newV) -> newV)
            );
}

Cas d'utilisation:

mapHeaderIndex(SomeHeaderEnum::getFieldByHeader);
mapHeaderIndex(AnotherHeaderEnum::getFieldByHeader);
0
Bananon 21 avril 2020 à 00:01
    public static <T> Map<T, Integer> mapHeadersIndex(List<String> headers, Function<String, T> keyMapper) {
        AtomicInteger index = new AtomicInteger();
        return headers.stream()
                .collect(Collectors.toMap(
                        keyMapper,
                        s -> index.getAndIncrement(),
                        (oldV, newV)->newV)
                );
    }
-1
Flavio Oliva 19 avril 2020 à 15:49

C'est le code que j'ai pu faire fonctionner jusqu'à présent:


    System.out.println(mapFieldIndex(SomeHeaderEnum::getFieldByHeader));
    System.out.println(mapFieldIndex(AnotherHeaderEnum::getFieldByHeader));

    protected Map<Enum<?>, Integer> mapFieldIndex(Function<String, Enum<?>> keyMapper) {
        AtomicInteger index = new AtomicInteger();
        return HEADERS.stream()
                .collect(Collectors.toMap(
                        keyMapper,
                        s -> index.getAndIncrement(),
                        (oldV, newV)->newV)
                );
    }

Une meilleure approche?

-1
Flavio Oliva 19 avril 2020 à 15:30