lambda erklärung - Warum implementiert java.util.Collection nicht die neue Stream-Schnittstelle?





streams map (2)


Ja, es gibt gute Gründe für diese Entscheidungen :)

Der Schlüssel ist der Unterschied zwischen eifrigen und faulen Operationen. Die Beispiele, die Sie unter der ersten Frage geben, zeigen eifrige Operationen, bei denen das Mappen oder Filtern einer Liste eine neue Liste erzeugt. Es ist nichts falsch daran, aber es ist oft nicht das, was du willst, weil du oft viel mehr arbeitest, als du brauchst; Eine eifrige Operation muss an jedem Element funktionieren und eine neue Sammlung produzieren. Wenn Sie mehrere Operationen erstellen (Filter-Map-Reduce), machen Sie eine Menge zusätzlicher Arbeit. Auf der anderen Seite komponieren faule Operationen wunderschön; wenn Sie tun:

 Optional<Person> tallestGuy = people.stream()
                                     .filter(p -> p.getGender() == MALE)
                                     .max(comparing(Person::getHeight));

Die Filter- und Reduktionsoperationen (max.) werden zu einem einzigen Durchgang verschmolzen. Dies ist sehr effizient.

Also, warum nicht die Stream-Methoden direkt auf der Liste verfügbar machen? Nun, wir haben es so versucht. Unter zahlreichen anderen Gründen haben wir festgestellt, dass das Mischen von trägen Methoden wie filter() und eifrigen Methoden wie removeAll() für die Benutzer verwirrend war. Durch Gruppieren der faulen Methoden in eine separate Abstraktion wird es viel klarer; Die Methoden in List sind diejenigen, die die Liste mutieren; Die Methoden in Stream sind diejenigen, die sich mit zusammensetzbaren, trägen Operationen an Datensequenzen beschäftigen, unabhängig davon, wo diese Daten sich befinden.

So, wie Sie es vorschlagen, ist es großartig, wenn Sie wirklich einfache Dinge tun wollen, aber beginnt auseinander zu fallen, wenn Sie versuchen, darauf aufzubauen. Ist die extra stream() Methode nervig? Sicher. Aber die Abstraktionen für Datenstrukturen (bei denen es in erster Linie um das Organisieren von Daten im Speicher geht) und Streams (bei denen es hauptsächlich darum geht, aggregiertes Verhalten zu bilden) trennen Skalen besser zu komplexeren Operationen.

Zu Ihrer zweiten Frage können Sie das relativ einfach tun: Implementieren Sie die Stream-Methoden wie folgt:

public<U> Stream<U> map(Function<T,U> mapper) { return convertToStream().map(mapper); }

Aber das schwimmt nur gegen den Strom; besser, nur eine effiziente stream () -Methode zu implementieren.

Ich brauchte nur etwas Zeit, um mich mit dem Java-8-Buzz über Streams und Lambdas zu beschäftigen. Was mich überrascht hat ist, dass Sie die Stream-Operationen wie .map() , .filter() direkt auf eine java.util.Collection .filter() . Gibt es einen technischen Grund, warum die Oberfläche java.util.Collection nicht mit Standardimplementierungen dieser Stream-Operationen erweitert wurde?

Etwas googelnd sehe ich viele Beispiele von Menschen, die nach dem Muster von:

List<String> list = someListExpression;
List<String> anotherList = list.stream().map(x -> f(x)).collect(Collectors.toList());

Das wird sehr ungeschickt, wenn Sie viele dieser Stream-Operationen in Ihrem Code haben. Da .stream() und .collect() für das, was Sie ausdrücken möchten, völlig irrelevant sind, möchten Sie lieber sagen:

List<String> list = someListExpression;
List<String> anotherList = list.map(x -> f(x));



Im Folgenden finden Sie eine Möglichkeit, Selenium-Testfälle von JMeter auszuführen:


JUnit Anfrage Sampler

Running Selenium testet diesen Weg vielleicht, wenn Sie bereits automatisierte (Java) Seleniumszenarien wiederverwenden wollen, anstatt JS-Skripte für WebDriver Sampler neu zu schreiben.

Selen RC

  1. Selenium Testprojekt und Setup vorbereiten.

    1.1. Laden Sie Selenium Java-Client-Bibliotheken herunter und setzen Sie selenium-java-${version}.jar in den JMeter-Klassenpfad, zB %JMETER_HOME%/lib/ .
    1.2. Selenserver sollte auf und hören sein:

    java -jar selenium-server-standalone-${version}.jar
    

    1.3. Selenium- %JMETER_HOME%/lib/junit/ als .jar %JMETER_HOME%/lib/junit/ und in %JMETER_HOME%/lib/junit/ speichern.

    HINWEIS: Ihre TestCase sollte TestCase oder SeleneseTestCase , damit JMeter diesen SeleneseTestCase abholen kann. Der Name des Testfalls sollte mit "test" beginnen .
    HINWEIS: Standardmäßig erweitert SeleneseTestCase JUnit 3.x TestCase , auch SeleneseTestCase erwartet, dass der externe Selenium-Server ausgeführt wird.

  2. Konfigurieren Sie den JUnit Request-Sampler

    2.1. Fügen Sie in JMeter Testplan JUnit Request Sampler hinzu .
    Legen Sie den Class Name gemäß dem Selenium-Testplan fest.
    Test Method die Testmethode fest, um zu testen, ob sie ausgeführt werden soll.
    Belassen Sie andere Parameter standardmäßig.

    JUnit 3.x vs. 4.x
    JUnit Request Sampler kann sowohl JUnit3- als auch JUnit4-style-Klassen und -Methoden verarbeiten. Um den Sampler so einzustellen, dass er nach JUnit 4-Tests ( @Test Annotationen) Search for Junit4 annotations (instead of JUnit 3) @Test Kontrollkästchen Search for Junit4 annotations (instead of JUnit 3) in den obigen Einstellungen.
    Die folgenden JUnit4-Annotationen werden erkannt:

    @Test - verwendet, um Testmethoden und Klassen zu finden. Die Attribute "expected" und "timeout" werden unterstützt.
    @Before - behandelt dasselbe wie setUp () in JUnit3
    @After - behandelt die gleiche wie tearDown () in JUnit3
    @BeforeClass, @AfterClass - werden als Testmethoden behandelt, so dass sie bei Bedarf unabhängig voneinander ausgeführt werden können

  3. Sie können jetzt Ihren Selenium-Test mit JMeter starten.

Java-Code für den JUnit Request-Sampler:

JUnit 3.x

package com.example.tests;

import com.thoughtworks.selenium.*;

public class selenium extends SeleneseTestCase {

    private static Selenium selenium;

    public void setUp() throws Exception {
        selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
        selenium.start();
        selenium.windowMaximize();
    }

    public void testSelenium() throws Exception {
        selenium.open("/");
        selenium.waitForPageToLoad("30000");
        Assert.assertEquals("Google", selenium.getTitle());
    }

    public void tearDown() throws Exception {
        selenium.close();
    }
}

JUnit 4.x

Das in JUnit 4 geschriebene Testskript verwendet JUnit-Annotationen:

package com.example.tests;

import com.thoughtworks.selenium.*;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class selenium extends SeleneseTestCase {

    private static Selenium selenium;

    @Before
    public void setUp() throws Exception {
        selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
        selenium.start();
        selenium.windowMaximize();
    }

    @Test
    public void testSelenium() throws Exception {
        selenium.open("/");
        selenium.waitForPageToLoad("30000");
        Assert.assertEquals("Google", selenium.getTitle());
    }

    @After
    public void tearDown() throws Exception {
        selenium.stop();
    }
}

Selenium Webtreiber

Dieser Fall ist eine Alternative zu WebDriver Sampler, die unten in einer anderen Antwort erwähnt wird.

Voraussetzungen

Der einzige Unterschied mit dem Selenium RC Gehäuse ist Selen Setup Vorbereitung:

1.1. Laden Sie %JMETER_HOME%/lib/ selenium-server-standalone-${version}.jar herunter und setzen Sie es in den JMeter Klassenpfad, zB %JMETER_HOME%/lib/ .
HINWEIS: Der Selenium-Server muss nicht gestartet werden.

Alle anderen Schritte sind dieselben wie im oben beschriebenen Szenario.


package org.openqa.selenium.example;

import junit.framework.TestCase;

import org.junit.Before;
import org.junit.Test;
import org.junit.After;
import org.openqa.selenium.*;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxProfile;

public class selenium extends TestCase {
    public static WebDriver driver;

    @Before
    public void setUp() {
        FirefoxProfile profile = new FirefoxProfile();
        driver = new FirefoxDriver(profile);
    }

    @Test
    public void testSelenium() throws Exception {
        driver.get("http://www.google.com/");
        Assert.assertEquals("Google", driver.getTitle());
    }

    @After
    public void tearDown() {
        driver.quit();
    }
}

Upd.

Weitere gute Punkte und Schritt-für-Schritt-Anleitungen zur Verwendung des Selenium + JUnit + JMeter-Bundles:

BeanShell-Sampler

In diesem Fall wird das Selentestszenario direkt im BeanShell Sampler von JMeter ausgeführt.

  1. Selenium Setup Vorbereitung ist völlig identisch mit den oben beschriebenen Fällen: Download Selenium-Bibliotheken, setzen Sie auf JMeter Klassenpfad, Start Selenium Server (im Falle von Selenium RC).
  2. Setzen Sie Ihr Selentestszenario in BeanShell Sampler:

Selen RC

import com.thoughtworks.selenium.*;
import java.util.regex.Pattern;

Boolean result = true;

try {
    selenium = new DefaultSelenium("localhost", 4444, "*iexplore", "http://www.google.com/");
    selenium.start();
    selenium.windowMaximize();

    selenium.open("/");
    selenium.waitForPageToLoad("30000");  

    if (!selenium.isTextPresent("Google")) result = false;
} catch (Exception ex) {
    ex.printStackTrace();
    IsSuccess = false;
    ResponseCode = "500";
    ResponseMessage = ex.getMessage();
} finally {
    selenium.stop();
}

IsSuccess = result;
return result;

Selenium Webtreiber

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;

Boolean result = true;

try {
    driver = new HtmlUnitDriver();
    driver.setJavascriptEnabled(true);

    driver.get("http://www.google.com/");

    if (!driver.getTitle().contains("Google")) result = false;
} catch (Exception ex) {
    ex.printStackTrace();
    IsSuccess = false;
    ResponseCode = "500";
    ResponseMessage = ex.getMessage();
} finally {
    driver.quit();
}

IsSuccess = result;
return result;

JSR223 Sampler + Groovy

In diesem Fall wird das Selentest -Szenario über JSR223 Sampler + Groovy .
Für Leistungsüberlegungen scheint dieser Ansatz vorzuziehen, als den oben beschriebenen BeanShell-Sampler zu verwenden.

  1. Selenium Setup Vorbereitung ist völlig identisch mit den oben beschriebenen Fällen: Download Selenium-Bibliotheken, setzen Sie auf JMeter Klassenpfad, Start Selenium Server (im Falle von Selenium RC).
  2. Fügen Sie Groovy-Unterstützung für JSR223 Sampler hinzu:

    2.1. Download der neuesten Groovy- Binärdistribution;
    2.2. Kopieren Sie groovy-all-${VERSION}.jar aus dem Ordner "embeddable" der Distribution und legen Sie es in %JMETER_HOME%/lib/ ;
    2.3. JMeter neu starten.

  3. Konfigurieren Sie den JSR233-Sampler:

    3.1. füge JSR233-Sampler zur Thread-Gruppe hinzu;
    3.2. setze Script Language in den Einstellungen des Samplers auf groovy ;
    3.3. Setzen Sie Ihr Selentest-Szenario in den Script (Java-Code wird akzeptiert):

Selen RC

import com.thoughtworks.selenium.*;
import java.util.regex.Pattern;

Boolean result = true;

try {
    selenium = new DefaultSelenium("localhost", 4444, "*iexplore", "http://www.google.com/");
    selenium.start();
    selenium.windowMaximize();

    selenium.open("/");
    selenium.waitForPageToLoad("30000");      

    if (!selenium.isTextPresent("Google")) result = false;
} catch (Exception ex) {
    ex.printStackTrace();
    log.error(ex.getMessage());
     SampleResult.setSuccessful(false);
     SampleResult.setResponseCode("500");
     SampleResult.setResponseMessage(ex.getMessage());
} finally {
    selenium.stop();
}

SampleResult.setSuccessful(result);
return result;

Selenium Webtreiber

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;

Boolean result = true;

try {
    driver = new HtmlUnitDriver();
    driver.setJavascriptEnabled(true);

    driver.get("http://www.google.com/");

    if (!driver.getTitle().contains("Google")) result = false;
} catch (Exception ex) {
    ex.printStackTrace();
    log.error(ex.getMessage());
     SampleResult.setSuccessful(false);
     SampleResult.setResponseCode("500");
     SampleResult.setResponseMessage(ex.getMessage());
} finally {
    driver.quit();
}

SampleResult.setSuccessful(result);
return result;

Gemeinsame Notizen für BeanShell / JSR223 Sampler Fälle:

  • Verwenden Sie externe .bsh / .groovy-Dateien mit Testszenario (Skriptdateifeld), anstatt Beanshell / Groovy-Code direkt im Sampler für intensive Tests zu verwenden.
  • Da BeanShell / JSR233 Sampler Zugriff auf JMeter-Variablen haben, können Sie den Teststatus (= Sampler-Ausführung) direkt im Testszenario (z. B. IsSuccess = STATUS oder SampleResult.setSuccessful(STATUS) , siehe oben) setzen, ohne Response Assertion zu verwenden.




java lambda functional-programming java-8 java-stream