Get rid of ugly if statements

后端 未结 25 2202
借酒劲吻你
借酒劲吻你 2020-12-02 05:59

I have this ugly code:

if ( v > 10 ) size = 6;
if ( v > 22 ) size = 5;
if ( v > 51 ) size = 4;
if ( v > 68 ) size = 3;
if ( v > 117 ) size = 2         


        
25条回答
  •  臣服心动
    2020-12-02 06:41

    Here is an object-oriented solution, a class called Mapper that maps values from any type that implements comparable to any target type.

    Syntax:

    Mapper mapper = Mapper.from("a","b","c").to(1,2,3);
    
    // Map a single value
    System.out.println(mapper.map("beef")); // 2
    
    // Map a Collection of values
    System.out.println(mapper.mapAll(
        Arrays.asList("apples","beef","lobster"))); // [1, 2, 3]
    

    Code:

    public class Mapper, T> {
    
        private final S[] source;
        private final T[] target;
    
        // Builder to enable from... to... syntax and
        // to make Mapper immutable
        public static class Builder> {
            private final S2[] data;
            private Builder(final S2[] data){
                this.data = data;
            }
            public  Mapper to(final T2... target){
                return new Mapper(this.data, target);
            }
        }
    
    
        private Mapper(final S[] source, final T[] target){
            final S[] copy = Arrays.copyOf(source, source.length);
            Arrays.sort(copy);
            this.source = copy;
            this.target = Arrays.copyOf(target, target.length);
        }
    
        // Factory method to get builder
        public static , V> Builder from(final U... items){
            return new Builder(items);
        }
    
        // Map a collection of items
        public Collection mapAll(final Collection input){
            final Collection output = new ArrayList(input.size());
            for(final S s : input){
                output.add(this.map(s));
            }
            return output;
        }
    
        // map a single item
        public T map(final S input){
            final int sourceOffset = Arrays.binarySearch(this.source, input);
            return this.target[
                Math.min(
                    this.target.length-1,
                    sourceOffset < 0 ? Math.abs(sourceOffset)-2:sourceOffset
                )
            ];
        }
    }
    

    Edit: finally replaced the map() method with a more efficient (and shorter) version. I know: a version that searches partitions would still be faster for large arrays, but sorry: I'm too lazy.

    If you think this is too bloated, consider this:

    1. It contains a builder that lets you create the Mapper using varargs syntax. I'd say that's a must-have for usability
    2. It contains both a single item and a collection mapping method
    3. It's immutable and hence thread safe

    Sure, all of these features could be easily removed, but the code would be less complete, less usable or less stable.

提交回复
热议问题