¿Es posible la creación de la aplicación corriente que cuenta sus elementos en una sola operación

Vishwa Ratna:

Q: ¿Es posible crear la aplicación corriente que cuenta sus elementos en una sola operación en lugar de contar todos y cada elemento en la corriente?

Vine a esto, sin embargo, cuando me trató de comparar los dos métodos en una lista:

  • size()

  • count()

Stream::countel funcionamiento del terminal cuenta el número de elementos en una corriente. La complejidad de la operación es a menudo O (N) , lo que significa que el número de sub-operaciones es proporcional al número de elementos de la corriente .

List::sizemétodo tiene una complejidad de O (1) , lo que significa que, independientemente del número de elementos en la lista, el size()método devolverá en tiempo constante.

   List<Integer> list = IntStream.range(0, 100).boxed().collect(toList());
    System.out.println(list.size());
    System.out.println(list.stream().count());

size()tomó un tiempo inferior relativa que count(), por lo que ¿hay alguna manera posible crear la aplicación corriente que cuenta sus elementos en una sola operación y hacer una complejidad de O (1) ??


Editar artículo para responder Sí :

Es posible crear Streamla aplicación que cuenta sus elementos en una única operación de O (1) en lugar de contar todos y cada elemento en la corriente. Esto puede mejorar significativamente el rendimiento, especialmente para los flujos con muchos elementos.

Holger:

Esto ya está ocurriendo en Java 9 y posteriores (teniendo en cuenta la implementación OpenJDK, que es también la base para el JDK de Oracle).

Si quieres una operación similar, se puede utilizar, por ejemplo,

public static long count(BaseStream<?,?> s) {
    Spliterator<?> sp = s.spliterator();
    long c = sp.getExactSizeIfKnown();
    if(c >= 0) return c;
    final class Counter implements Consumer<Object>,
        IntConsumer, LongConsumer, DoubleConsumer { // avoid boxing where possible
        long count;
        public void accept(Object t) { count++; }
        public void accept(int value) { count++; }
        public void accept(long value) { count++; }
        public void accept(double value) { count++; }
    }
    Counter c = new Counter();
    sp.forEachRemaining(c);
    return c.count;
}

Puede comprobar que no va a procesar todos los elementos con

System.out.println(count(IntStream.range(0, 100).peek(System.out::println)));
System.out.println(count(Stream.of("a", "b", "c").peek(System.out::println)));

mientras que la inserción de una filteroperación como

System.out.println(count(Stream.of("a", "b", "c")
    .peek(System.out::println).filter(x -> true)));

hará que el recuento imprevisibles y que requieren un recorrido.

Como se dijo anteriormente, en JDK 9 o, puede utilizar simples

System.out.println(Stream.of("a", "b", "c").peek(System.out::println).count());

y

System.out.println(Stream.of("a", "b", "c")
    .peek(System.out::println).filter(x -> true).count());

ver que el recorrido no sucede cuando el recuento es predecible.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=167869&siteId=1
Recomendado
Clasificación