Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 摆脱丑陋的if语句_Java_Coding Style - Fatal编程技术网

Java 摆脱丑陋的if语句

Java 摆脱丑陋的if语句,java,coding-style,Java,Coding Style,我有一个丑陋的密码: 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; if ( v > 145 ) size = 1; return size; 如何摆脱多个if语句 if ( v > 145 ) size = 1; else if ( v > 117 )

我有一个丑陋的密码:

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;
if ( v > 145 ) size = 1;
return size;
如何摆脱多个if语句

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

return size;     
这更适合你的情况

如果可能,您也可以选择开关箱

更新:

如果您分析了“v”的值,那么它通常位于较低的范围内(这是我的尝试

更新:已修复。以前的解决方案对精确值(10,22,51…)给出了不正确的答案。对于if val<10,此解决方案默认为6

静态int-Foo(int-val)
{
//6, 5, 4, 3, 2 ,1
int[]v=新的int[]{10,22,51,68117145};
int pos=Arrays.binarySearch(v,val-1);
如果(pos<0)pos=~pos;
如果(位置>0)位置--;
返回6位;
}

这种方法怎么样:

int getSize(int v) {
    int[] thresholds = {145, 117, 68, 51, 22, 10};

    for (int i = 0; i < thresholds.length; i++) {
        if (v > thresholds[i]) return i+1;
    }
    return 1;
}
if ( v > 145 ) return 1;
if ( v > 117 ) return 2;
if ( v >  68 ) return 3;
if ( v >  51 ) return 4;
if ( v >  22 ) return 5;
if ( v >  10 ) return 6;
return ...;     // The <= 10 case isn't handled in the original code snippet. 
int[]arr=newint[]{145,117,68,51,22,10};
对于(int index=0;indexarr[index])返回1+索引;
}
返回默认值;

使用
NavigableMap
API:

NavigableMap<Integer, Integer> s = new TreeMap<Integer, Integer>();
s.put(10, 6);
s.put(22, 5);
s.put(51, 4);
s.put(68, 3);
s.put(117, 2);
s.put(145, 1);

return s.lowerEntry(v).getValue();
NavigableMap s=newtreemap();
s、 put(10,6);
s、 put(22,5);
s、 put(51,4);
s、 put(68,3);
s、 put(117,2);
s、 put(145,1);
返回s.lowerEntry(v).getValue();

这里有大量的答案和建议,但老实说,我没有看到任何一个比原来的方法“更漂亮”或“更优雅”


如果你有几十个或几百个迭代要检查,那么我可以很容易地看到一些for循环,但是老实说,对于你所做的少数比较,坚持使用If并继续。它并没有那么难看。

这里有一个面向对象的解决方案,一个名为
Mapper
的类,它映射来自任何实现可比的类型的值任何目标类型

语法:

Mapper<String, Integer> 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]
public class Mapper<S extends Comparable<S>, T> {

    private final S[] source;
    private final T[] target;

    // Builder to enable from... to... syntax and
    // to make Mapper immutable
    public static class Builder<S2 extends Comparable<S2>> {
        private final S2[] data;
        private Builder(final S2[] data){
            this.data = data;
        }
        public <T2> Mapper<S2, T2> to(final T2... target){
            return new Mapper<S2, T2>(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 <U extends Comparable<U>, V> Builder<U> from(final U... items){
        return new Builder<U>(items);
    }

    // Map a collection of items
    public Collection<T> mapAll(final Collection<? extends S> input){
        final Collection<T> output = new ArrayList<T>(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
            )
        ];
    }
}
Mapper-Mapper=Mapper.from(“a”、“b”、“c”)到(1,2,3);
//映射单个值
System.out.println(mapper.map(“beef”);//2
//映射一组值
System.out.println(mapper.mapAll(
数组.asList(“苹果”、“牛肉”、“龙虾”);/[1,2,3]
代码:

Mapper<String, Integer> 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]
public class Mapper<S extends Comparable<S>, T> {

    private final S[] source;
    private final T[] target;

    // Builder to enable from... to... syntax and
    // to make Mapper immutable
    public static class Builder<S2 extends Comparable<S2>> {
        private final S2[] data;
        private Builder(final S2[] data){
            this.data = data;
        }
        public <T2> Mapper<S2, T2> to(final T2... target){
            return new Mapper<S2, T2>(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 <U extends Comparable<U>, V> Builder<U> from(final U... items){
        return new Builder<U>(items);
    }

    // Map a collection of items
    public Collection<T> mapAll(final Collection<? extends S> input){
        final Collection<T> output = new ArrayList<T>(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
            )
        ];
    }
}
公共类映射器{
私人最终S[]来源;
私人最终目标;
//生成器以启用从…到…语法和
//使映射器不可变
公共静态类生成器{
私人最终数据;
私人建筑商(最终S2[]数据){
这个数据=数据;
}
公共映射到(最终T2…目标){
返回新映射器(this.data,target);
}
}
专用映射器(最终S[]源,最终T[]目标){
final S[]copy=Arrays.copyOf(source,source.length);
数组。排序(复制);
this.source=复制;
this.target=Arrays.copyOf(target,target.length);
}
//获取生成器的工厂方法
来自的公共静态生成器(最终U…项){
返回新的生成器(项目);
}
//映射项目集合

公共集合mapAll(最终集合我的评论功能还没有打开,希望没有人会根据我的回答说“正确”

美化丑陋的代码可以/应该被定义为试图实现:

  • 可读性(好的,说明显而易见的——也许是问题的多余部分)
  • 性能——最好的情况是寻求最优,最坏的情况下,这不是一个大的消耗
  • 实用主义——这与大多数人做事的方式并不遥远,考虑到一个不需要优雅或独特解决方案的普通问题,以后改变它应该是一种自然的努力,不需要太多回忆
  • 在我看来,org.life.java给出的答案是最漂亮、最容易阅读的。出于阅读和性能的考虑,我还喜欢条件的编写顺序

    在我写这篇文章的时候,回顾一下关于这个主题的所有评论,似乎只有org.life.java提出了性能问题(也可能是mfloryan,说某些东西会“更长”)。当然,在大多数情况下,考虑到这个例子,无论你如何写,它都不应该承受明显的减速

    但是,通过嵌套条件并对条件进行优化排序,可以提高性能[值得,特别是在循环的情况下]


    所有这些,嵌套和排序条件(比您的示例更复杂)由实现尽可能快的执行的决心所带来的结果通常会产生可读性较差的代码,并且代码更难更改。我再次提到#3,实用主义…平衡需求。

    这有一个基本的数学规则吗?如果有,你应该使用它:但只有当它来自问题领域,而不仅仅是一些公式时这正好符合实际情况。

    我觉得原始代码很好,但如果您不介意多次返回,您可能更喜欢表格化的方法:

    int getSize(int v) {
        int[] thresholds = {145, 117, 68, 51, 22, 10};
    
        for (int i = 0; i < thresholds.length; i++) {
            if (v > thresholds[i]) return i+1;
        }
        return 1;
    }
    
    if ( v > 145 ) return 1;
    if ( v > 117 ) return 2;
    if ( v >  68 ) return 3;
    if ( v >  51 ) return 4;
    if ( v >  22 ) return 5;
    if ( v >  10 ) return 6;
    return ...;     // The <= 10 case isn't handled in the original code snippet. 
    
    if(v>145)返回1;
    如果(v>117)返回2;
    如果(v>68)返回3;
    如果(v>51),返回4;
    如果(v>22),返回5;
    如果(v>10)返回6;
    
    return…;//这是我的代码示例,使用SortedSet。您可以初始化边界一次

    SortedSet<Integer> boundaries = new SortedSet<Integer>;
    
    boundaries.add(10);
    
    boundaries.add(22);
    
    boundaries.add(51);
    
    boundaries.add(68);
    
    boundaries.add(117);
    
    boundaries.add(145);
    
    SortedSet边界=新的SortedSet;
    增加(10);
    增加(22);
    增加(51);
    增加(68);
    增加(117);
    增加(145);
    
    然后,随后以这种方式将其用于v的多个值(和初始化大小)

    SortedSet子集=边界。尾集(v);
    if(subset.size()!=bounders.size())
    size=subset.size()+1;
    
    为了完整起见,我建议您可以设置一个包含145个元素的数组大小,这样答案就可以直接作为大小[v]返回。请原谅我没有写出全部内容。当然,您必须确保v在范围内

    我能想到这样做的唯一原因是,如果你要创建一次数组,并在一个必须非常快的应用程序中使用它数千次。我提到它是一个在内存和速度(不是以前的问题)之间以及在设置时间和时间之间进行权衡的例子
    if ( v > 145 ) return 1;
    if ( v > 117 ) return 2;
    if ( v >  68 ) return 3;
    if ( v >  51 ) return 4;
    if ( v >  22 ) return 5;
    if ( v >  10 ) return 6;
    return ...;     // The <= 10 case isn't handled in the original code snippet. 
    
    return (v-173) / -27;
    
    SortedSet<Integer> boundaries = new SortedSet<Integer>;
    
    boundaries.add(10);
    
    boundaries.add(22);
    
    boundaries.add(51);
    
    boundaries.add(68);
    
    boundaries.add(117);
    
    boundaries.add(145);
    
    SortedSet<Integer> subset =  boundaries.tailSet(v);
    if( subset.size() != boundaries.size() )
      size = subset.size() + 1;
    
    if (v > 68) {
       if (v > 145) {
          return 1
       } else if (v > 117) {
          return 2;
       } else {
          return 3;
       }
    } else {
       if (v > 51) {
          return 4;
       } else if (v > 22) {
          return 5;
       } else {
          return 6;
       }
    }
    
    size = round(k_0 + k_1 * v + k_2 * v^2 + ...)
    
    -9.1504e-91 1.1986e-87 -5.8366e-85 1.1130e-82 -2.8724e-81 3.3401e-78 -3.3185e-75  9.4624e-73 -1.1591e-70 4.1474e-69 3.7433e-67 2.2460e-65 -6.2386e-62 2.9843e-59 -7.7533e-57 7.7714e-55 1.1791e-52 -2.2370e-50 -4.7642e-48 3.3892e-46 3.8656e-43 -6.0030e-41 9.4243e-41 -1.9050e-36 8.3042e-34 -6.2687e-32 -1.6659e-29 3.0013e-27 1.5633e-25 -8.7156e-23  6.3913e-21 1.0435e-18 -3.0354e-16 3.8195e-14 -3.1282e-12 1.8382e-10 -8.0482e-09 2.6660e-07 -6.6944e-06 1.2605e-04 -1.7321e-03 1.6538e-02 -1.0173e-01 8.3042e-34 -6.2687e-32 -1.6659e-29 3.0013e-27 1.5633e-25 -8.7156e-23 6.3913e-21 1.0435e-18 -3.0354e-16 3.8195e-14 -3.1282e-12 1.8382e-10 -8.0482e-09 2.6660e-07 -6.6944e-06 1.2605e-04 -1.7321e-03 1.6538e-02 -1.0173e-01 3.6100e-01 -6.2117e-01 6.3657e+00
    
    final int minBoundary = 10;
    final int maxBoundary = 145;
    final int maxSize = 6;
    Vector<Integer> index = new Vector<Integer>(maxBoundary);
        // run through once and set the values in your index
    
    if( v > minBoundary )
    {
       size = (v > maxBoundary ) ? maxSize : index[v];
    }
    
    CREATE TABLE VSize (
       LowerBound int NOT NULL CONSTRAINT PK_VSize PRIMARY KEY CLUSTERED,
       Size int NOT NULL
    )
    INSERT VSize VALUES (10, 6)
    INSERT VSize VALUES (22, 5)
    INSERT VSize VALUES (51, 4)
    INSERT VSize VALUES (68, 3)
    INSERT VSize VALUES (117, 2)
    INSERT VSize VALUES (145, 1)
    
    CREATE PROCEDURE VSizeLookup
       @V int,
       @Size int OUT
    AS
    SELECT TOP 1 @Size = Size
    FROM VSize
    WHERE @V > LowerBound
    ORDER BY LowerBound
    
    int getIndex(int v, int[] descArray) {
        for(int i = 0; i < descArray.length; i++)
            if(v > descArray[i]) return i + 1;
        return 0;
    }
    
    def size = { v -> [145,117,68,51,22,10].inject(1) { s, t -> v > t ? s : s + 1 } }
    
    7 - (x>10 + x>22 + x>51 + x>68 + x>117 + x>145)
    
                if (v <= 10)
                    return size;
                else {
                    size = 1;
    
                    if (v > 145)
                        return size;
                    else if (v > 117)
                        return ++size;
                    else if (v > 68)
                        return (size+2);
                    else if (v > 51)
                        return (size+3);
                    else if (v > 22)
                        return (size+4);
                    else if (v > 10)
                        return (size+5);
                }
    
      //int v = 9;
      int[] arr = {145, 117, 68, 51, 22, 10};
      int size = 7; for(;7 - size < arr.length && v - arr[size - 2] > 0; size--) {};
      return size;
    
    public int getSize(int input)
        {
            int size = 0;
            switch(input)
            {
            case 10:
                size = 6;
                break;
    
            case 22:
                size = 5;
                break;
    
    
            case 51:
                size = 4;
                break;
    
            case 68:
                size = 3;
                break;
    
            case 117:
                size = 2;
                break;
    
            case 145:
                size = 1;
                break;
            }
    
            return size;
        }
    
    ; On entry
    ;   r0 - undefined
    ;   r1 - value to test
    ;   lr - return address
    ; On exit
    ;   r0 - new value or preserved
    ;   r1 - corrupted
    ;
    wtf
            SUBS    r1, r1, #10
            MOVLE   pc, lr
            CMP     r1, #135
            MOVGT   r0, #1
            ADRLE   r0, lut
            LDRLEB  r0, [r0, r1]
            MOV     pc, lr
    ;
    ; Look-up-table
    lut
            DCB     0   ; padding
            DCB     6   ; r1 = 11 on entry
            DCB     6
            DCB     6
            DCB     6
            DCB     6
            DCB     6
            DCB     6
            DCB     6
            DCB     6
            DCB     6
            DCB     6
            DCB     6
            DCB     5   ; r1 = 23 on entry
            DCB     5
            ...
            ALIGN