简体   繁体   中英

how can i improve upon Map<Integer, Map<Integer, Map<PAXType, BigDecimal>>> using guava

I have the following data structure for the entity relationships:

Map<Integer, Map<Integer, Map<PAXType, BigDecimal>>>

Entity Relationships:

  • 1 Package ( P ) has Many Variants ( V )
  • 1 Variants ( V ) has Many Price data-points
  • Price is based on the PAXType (which is an enum : Adult, Child, Infant)

I modelled this using:

Map<Package, Map<Variant, Map<PAXType, BigDecimal>>>

for the purpose of quick price lookup based on

  • package
  • package variant

The way I'm using this right now is: As I read data from the db, I create/update the above map. After I get all the info, for each variant, I need to transform the price map, from Map<PAXType, BigDecimal> to Map<OccupancyType, BigDecimal> , where OccupancyType is another enum. This is the final price format which I need to output for serialization etc.

Is there any data structure in guava which would be a good fit for the ugly map construct I have and support the operations I suggested above ?

In addition to Tomasz's answer suggesting encapsulating Map<PAXType, BigDecimal> in class PriceByType (note that if PAXType is an enum, you should use EnumMap) I think you should consider using Guava's Table as substitution for Map<Integer, Map<Integer, PriceByType>> . Table use case:

Typically, when you are trying to index on more than one key at a time, you will wind up with something like Map<FirstName, Map<LastName, Person>> , which is ugly and awkward to use. Guava provides a new collection type, Table, which supports this use case for any "row" type and "column" type.

Your indexes are package and package variant, both Integers, so table should end up with Table<Integer, Integer, PriceByType> .

Guava has nothing to do here, you need to create few objects with meaningful names. First encapsulate Map<PAXType, BigDecimal> into eg PriceByType class holding this map:

Map<Integer, Map<Integer, PriceByType>>

Now proceed with Map<Integer, PriceByType> in the same way:

Map<Integer, PriceByVariant>

The final map can be called priceByPackage . Now create few helper methods to query these classes effectively:

public class PriceByType {

    private final Map<PAXType, BigDecimal> byType = //...

    public BigDecimal find(PAXType type) {
        return byType.get(type);
    }

}

and:

public class PriceByVariant {

    private final Map<Integer, PriceByType> byVariant = //...

    public BigDecimal find(int variant, PAXType type) {
        //handle unknown values here
        return byVariant.get(variant).find(type);
    }

}

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