繁体   English   中英

性能与内存列表

[英]Performance vs memory Lists

什么会更好?

假设我们有一个类mainClass ,它有一个List<BigClass>List<Foo>foos ....

Foo本身有一个List<Boo>

如果目标是能够让所有的Boo的了的所有元素foos 如果用户要将新的Foo插入到foos那么在BigClass保留另一个List<Boo>然后插入相应的Boo元素会foos吗?

或者每次用户要求此列表时,从'BigClass'中生成这个总Boo列表会更好吗?

这里的主要问题是,你必须在这里选择性能与内存吗?

PS。 对不起广泛的标题,不太知道如何命名这个问题:/

您可以将这两种行为都放在一个实现中。 只需在mainClass中创建自己的List实现(可能是一个名为FooList的内部类,或者甚至是一个匿名的内部类)。 使FooList的方法透明地将所有单个Foo列表作为单个列表呈现。 例如,FooList.iterator()的实现将依次透明地在每个单独的Foo列表上实例化迭代器,这样它就会迭代通过单个大型列表。

如果你需要同时获得所有Boo并且还将Boo分组(即Boo属于某些Foo ),那么我会说最好的是返回BigClass包含的所有Boo视图 ,no他们属于哪个Foo

要实现此目的,您可以使用Google Guava IterablesJava 8 Stream.flatMap() ,具体取决于您的Java版本。

使用Google Guava:

class BigClass {

    List<Foo> foos = new LinkedList<Foo>();

    public Iterable<Boo> allBoos() {
        return Iterables.concat(this.foos);
    }
}

class Boo {
    final int a;

    Boo(int a) {
        this.a = a;
    }

    @Override
    public String toString() {
        return String.valueOf(this.a);
    }
}

class Foo
    implements Iterable<Boo> {

    List<Boo> boos = new LinkedList<Boo>();

    @Override
    public Iterator<Boo> iterator() {
        return this.boos.iterator();
    }
}

public class Sample {
    public static void main(String[] args) {

        Boo b1 = new Boo(1);
        Boo b3 = new Boo(3);
        Boo b5 = new Boo(5);

        Boo b2 = new Boo(2);
        Boo b4 = new Boo(4);
        Boo b6 = new Boo(6);

        Foo odd = new Foo();
        odd.boos.addAll(Arrays.asList(b1, b3, b5));

        Foo even = new Foo();
        even.boos.addAll(Arrays.asList(b2, b4, b6));

        BigClass b = new BigClass();
        b.foos.add(odd);
        b.foos.add(even);

        System.out.println(b.allBoos()); // [1, 3, 5, 2, 4, 6]
    }
}

这种方法的最好之处在于Guava返回的Iterable懒惰的 ,这意味着没有创建新的集合或列表并填充任何元素。 相反,返回的Iterable是一个视图,其Iterator消耗第一个Iterable元素,当用尽时,“跳转”到下一个Iterable并消耗其元素,并“跳转”到下一个,依此类推,直到最后一个元素最后一个Iterable被消耗掉了。

使用Java 8:

class BigClass {

    List<Foo> foos = new LinkedList<Foo>();

    public Iterable<Boo> allBoos() {
        Stream<Boo> s = this.foos.stream().flatMap(
            f -> f.getBoos().stream());
        return s::iterator;
    }
}

class Boo {
    final int a;

    Boo(int a) {
        this.a = a;
    }

    @Override
    public String toString() {
        return String.valueOf(this.a);
    }
}

class Foo {

    List<Boo> boos = new LinkedList<Boo>();

    public List<Boo> getBoos() {
        return this.boos;
    }
}

public class Sample {
    public static void main(String[] args) {

        Boo b1 = new Boo(1);
        Boo b3 = new Boo(3);
        Boo b5 = new Boo(5);

        Boo b2 = new Boo(2);
        Boo b4 = new Boo(4);
        Boo b6 = new Boo(6);

        Foo odd = new Foo();
        odd.boos.addAll(Arrays.asList(b1, b3, b5));

        Foo even = new Foo();
        even.boos.addAll(Arrays.asList(b2, b4, b6));

        BigClass b = new BigClass();
        b.foos.add(odd);
        b.foos.add(even);

        List<Boo> list = new ArrayList<>();
        b.allBoos().forEach(boo -> list.add(boo));

        System.out.println(list); // [1, 3, 5, 2, 4, 6]
    }
}

关于懒惰的相同考虑适用于此。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM