11

I have an enum with another enum as a parameter

public enum MyEntity{
   Entity1(EntityType.type1,
    ....


   MyEntity(EntityType type){
     this.entityType = entityType;
   }
}

I want to create a method that return the enum by type

public MyEntity getEntityTypeInfo(EntityType entityType) {
        return lookup.get(entityType);
    }

usually I would have written

private static final Map<EntityType, EntityTypeInfo> lookup = new HashMap<>();

static {
    for (MyEntity d : MyEntity.values()){
        lookup.put(d.getEntityType(), d);
    }
}

What is the best practice to write it with java stream?

Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
Bick
  • 17,833
  • 52
  • 146
  • 251

2 Answers2

20

I guess there are some typos in your code (the method should be static in my opinion, your constructor is doing a no-op at the moment), but if I'm following you, you can create a stream from the array of enums and use the toMap collector, mapping each enum with its EntityType for the keys, and mapping the instance itself as a value:

private static final Map<EntityType, EntityTypeInfo> lookup =
    Arrays.stream(EntityTypeInfo.values())
          .collect(Collectors.toMap(EntityTypeInfo::getEntityType, e -> e));

The toMap collector does not make any guarantee about the map implementation returned (although it's currently a HashMap), but you can always use the overloaded variant if you need more control, providing a throwing merger as parameter.

You could also use another trick with a static class, and fill the map in the constructor.

Community
  • 1
  • 1
Alexis C.
  • 91,686
  • 21
  • 171
  • 177
  • 2
    You can improve this with `Function.identity()` instead of `e -> e` as `Function.identity()` always returns the same function. – dustin.schultz Feb 09 '16 at 22:17
  • 1
    @dustin.schultz `e -> e` is exactly the same, as this lambda expression does not capture values, it will be a singleton that is re-used at each invocation. Furthermore, `Function.identity()` is implemented as `return t -> t;`. – Alexis C. Feb 09 '16 at 22:35
  • 1
    Ah yes, doesn't capture, so uses singleton. I still think Function.identity() is very-slightly more clear. :) – dustin.schultz Feb 09 '16 at 22:42
  • 2
    @dustin.schultz Matter of taste, I guess. I find `e -> e` really explicit and shorter but everyone has its own preference ;-). – Alexis C. Feb 09 '16 at 22:44
  • `Stream.of()` is nicer than `Arrays.stream()` :) – aliopi Jul 27 '17 at 13:16
  • @aliopi `Stream.of(T... values)` calls `Arrays.stream(values)`, internally.. Using Stream.of(...) would result in an additional array creation because of the varargs (T... values) – Melvin Sep 19 '22 at 15:03
5
public enum FibreSpeed {
        a30M( "30Mb Fibre Connection - Broadband Only", 100 ),
        a150M( "150Mb Fibre Connection - Broadband Only", 300 ),
        a1G( "1Gb Fibre Connection - Broadband Only", 500 ),
        b30M( "30Mb Fibre Connection - Broadband & Phone", 700 ),
        b150M( "150Mb Fibre Connection - Broadband & Phone", 900 ),
        b1G( "1Gb Fibre Connection - Broadband & Phone", 1000 );

        public String speed;
        public int    weight;

        FibreSpeed(String speed, int weight) {
            this.speed = speed;
            this.weight = weight;
        }

        public static Map<String, Integer> SPEEDS = Stream.of( values() ).collect( Collectors.toMap( k -> k.speed, v -> v.weight ) );
    }
dobrivoje
  • 848
  • 1
  • 9
  • 18