代码之家  ›  专栏  ›  技术社区  ›  Dan Rosenstark

语言技巧来缩短我的Java代码?[关闭]

  •  8
  • Dan Rosenstark  · 技术社区  · 15 年前

    我目前正在重新发现Java(最近使用Ruby很多),并且我喜欢编译的时间检查。这使得重构变得非常容易。但是,我怀念那种玩忽职守的人 each 循环。这是我最糟糕的密码。

    这是最短的吗? 我有一个收藏叫 looperTracks ,它具有实现 Looper . 我不想修改这个集合,但是我想遍历它的成员和 this (它还实现 活套 )

    List<Looper> allLoopers = new ArrayList<Looper>(looperTracks.length + 1);
    for (LooperTrack track : looperTracks) {
        allLoopers.add(track);
    }
    allLoopers.add(this);
    
    for (Looper looper : allLoopers) {
        // Finally! I have a looper
    

    我特别关注Java的新特性,从1.5开始我可能已经错过了。 对于这个问题我是 询问jruby和groovy,尽管我知道它们会为此工作。

    编辑: 抱歉(太多红宝石了!)… 跑道 属于类型 LooperTrack[] LooperTrack 器具 活套 .

    12 回复  |  直到 13 年前
        1
  •  7
  •   missingfaktor Kevin Wright    14 年前

    至少有两种内置的方法可以缩短代码:

    你可以用 Collection.addAll(Collection) 将集合中作为参数传递的每个元素追加到集合末尾的。

    List<Looper> allLoopers = new ArrayList<Looper>();
    
    ...
    
    allLoopers.addAll(looperTracks);
    allLoopers.add(this);
    
    for(Looper looper : allLoopers) {
      ...
    }
    

    或者可以使用将集合作为参数的构造函数:

    List<Looper> allLoopers = new ArrayList<Looper>(looperTracks);
    

    由于问题的变化:使用 java.util.Arrays 例如

    List<Looper> someLooperTracks = Arrays.asList(looperTracks). 
    

    这将把数组包装成 固定大小列表 .

        2
  •  8
  •   Yacoby    15 年前

    至少可以使用这样一个事实,即可以使用另一个集合作为基值来构造一个集合。根据 docs :

    构造包含指定集合的元素的列表,按集合的迭代器返回这些元素的顺序。ArrayList实例具有 初始容量为指定集合大小的110% .

    也就是说可能有足够的空间 this 不用做任何调整。

    List<Looper> allLoopers = new ArrayList<Looper>(looperTracks);
    allLoopers.add(this);
    
    for (Looper looper : allLoopers) {
        // Finally! I have a looper
    
        3
  •  6
  •   Viktor Klang    13 年前

    我觉得你不能把它改短…

    for (Looper looper : new ArrayList<Looper>(looperTracks){{ add(EnclosingClass.this); }}) {
        // Finally! I have all loopers
    }
    
        4
  •  4
  •   missingfaktor Kevin Wright    14 年前

    Guava 很容易做到:

    for (Looper looper : ObjectArrays.concat(looperTracks, this)) {}
    

    Here 是方法的文档 ObjectArrays#concat .

        5
  •  2
  •   dfa    15 年前

    我刚刚实现了一个 迭代器 属于 可迭代的 s(它是以一种更健壮/经过测试/审查的方式实现的 Guava Iterables.concat(Iterable...) ):

    // make a concatenation of iterables
    public static <T> Iterable<T> $(final Iterable<T> first, final Iterable<T>... iterables) {
        List<Iterator<T>> allIterables = new LinkedList<Iterator<T>>();
        allIterables.add(first.iterator());
    
        for (Iterable<T> iterable : iterables) {
            allIterables.add(iterable.iterator());
        }
    
        final Iterator<Iterator<T>> iterators = allIterables.iterator();
    
        return new Iterable<T>() {
    
            @Override
            public Iterator<T> iterator() {
                return new Iterator<T>() {
    
                    private Iterator<T> current = iterators.next();
    
                    @Override
                    public boolean hasNext() {
                        if (current.hasNext()) {
                            return true;
                        } else {
                            if (iterators.hasNext()) {
                                current = iterators.next();
                                return current.hasNext();
                            } else {
                                return false;
                            }
                        }
                    }
    
                    @Override
                    public T next() {
                        return current.next();
                    }
    
                    @Override
                    public void remove() {
                    }
                };
            }
        };
    }
    

    使用它,您的代码将变成:

    for (Looper looper : $($(looperTracks), this)) {
    
    }
    

    如果你关心的话,执行是我的一部分 Dollar library (发布为lgpl3)。

        6
  •  1
  •   ninesided    15 年前

    为什么不能将它们全部添加为构造函数调用的一部分?

    List<Looper> allLoopers = new ArrayList<Looper>(looperTracks);
    
    allLoopers.add(this);
    
    for(Looper looper : allLoopers) {
    ...
    }
    
        7
  •  1
  •   rsp    15 年前

    根据键入的内容,您可以使用:

    List<Looper> allLoopers = new ArrayList<Looper>(looperTracks);
    allLoopers.add(this);
    

    或:

    List<Looper> allLoopers = new ArrayList<Looper>(looperTracks.length + 1);
    allLoopers.addAll(looperTracks);
    allLoopers.add(this);
    
        8
  •  1
  •   deamon    15 年前

    如果由于groovy或jruby的动态特性而不想使用它们,那么应该考虑使用scala。Scala是静态类型的,但比Java更简洁。

        9
  •  1
  •   Alan Moore Chris Ballance    15 年前

    你需要把所有的东西都列在一张单子上吗?如果没有,这是怎么回事?

    for (Looper looper : looperTracks) {
        doSomething(looper);
    }
    doSomething(this);
    
        10
  •  1
  •   Carl    15 年前

    尝试

    Looper[] loop = new Looper[looperTracks.length + 1];
    System.arraycopy(looperTracks, 0, loop, 0, looperTracks.length);
    loop[looperTracks.length] = this;
    for (Looper l : loop) { ... }
    

    但老实说,为什么不直接遍历现有数组,然后对循环执行任何您想执行的操作 this 之后呢?

    这个 List -上面的版本如下:

    List<Looper> loop = new ArrayList<Looper>(Arrays.asList(looperTracks));
    loop.add(this);
    for (Looper l : loop) { ... }
    
        11
  •  0
  •   Alan Moore Chris Ballance    15 年前

    你可以尝试使用 immutable list 通过使用 nCopies() 方法。引用API参考资料,

    public static <T> List<T> nCopies(int n, T o)

    返回一个不可变列表,该列表由 指定对象的n个副本。 新分配的数据对象是 很小(它包含一个引用 到数据对象)。这种方法是 与 list.addall方法来增加列表。这个 返回的列表是可序列化的。

    这将避免第一次foreach迭代。

        12
  •  0
  •   James    14 年前

    我只是想把它扔掉,但不要试图让你的代码更短,以使其可读为代价。

    当我开始写代码的时候,可读代码一直是我的目标,因为我知道在未来的某个时候,无论是我自己还是其他人都会看到它,并且必须理解它。