protected UnitFactorMap complete ( ) { Set < Unit > units = new LinkedHashSet <> ( ) ; // Add reverse mappings for all populated units. for ( Unit from : factors . keySet ( ) ) { units . add ( from ) ; for ( Map . Entry < Unit , UnitFactor > entry : factors . get ( from ) . entrySet ( ) ) { Unit to = entry . getKey ( ) ; units . add ( to ) ; UnitFactor factor = entry . getValue ( ) ; set ( to , factor . rational ( ) . reciprocal ( ) , from , false ) ; } } // For each pair of units that differ, resolve the best conversion path // to produce a final conversion factor. for ( Unit from : units ) { for ( Unit to : units ) { if ( from == to ) { continue ; } // If a direct conversion exists continue. UnitFactor factor = get ( from , to ) ; if ( factor != null ) { continue ; } // Get or create the mapping. Map < Unit , UnitFactor > map = factors . get ( from ) ; if ( map == null ) { map = new EnumMap <> ( Unit . class ) ; factors . put ( from , map ) ; } // Resolve the conversion factor using the best path. factor = resolve ( from , to ) ; // If a factor exists we overwrite it if we can set a factor with a lower total precision. UnitFactor old = map . get ( from ) ; // Add this conversion factor if none exists or if this factor's precision // is lower than the existing conversion. Rational rational = factor . rational ( ) ; if ( old == null || totalPrecision ( rational ) < totalPrecision ( old . rational ( ) ) ) { set ( from , rational , to , true ) ; } } } // Finally, sort the units from largest to smallest, where possible. List < Unit > unitList = new ArrayList <> ( Unit . forCategory ( category ) ) ; unitList . sort ( ( a , b ) -> { UnitFactor f = get ( a , b ) ; // Units in some categories cannot be compared so return an arbitrary order. if ( f == null ) { return - 1 ; } BigDecimal r = f . rational ( ) . compute ( RoundingMode . HALF_EVEN ) ; return BigDecimal . ONE . compareTo ( r ) ; } ) ; // Update the unit ordering map with the indices from the sorted list. for ( int i = 0 ; i < unitList . size ( ) ; i ++ ) { unitOrder . put ( unitList . get ( i ) , i ) ; } return this ; }
Creates direct conversion factors between all units by resolving the best conversion path and setting an explicit mapping if one does not already exist .