# Ermittlung eines doppelte Paars mit Streams



## Xyz1 (1. Sep 2019)

Fortführung von https://www.java-forum.org/thema/fr...-doppelte-paars-aus-sotieralgorithmus.185687/

Nicht schön, aber hier ist die Stream Lösung

```
@SuppressWarnings("unchecked")
public static List<Integer> highest_pair(int... a) {
    List<Integer> b = Arrays.stream(a).boxed().collect(Collectors.toList());
    return IntStream.range(0, a.length - 1).mapToObj(e -> b.subList(e, e + 2)).filter(e -> e.get(0) == e.get(1))
            .sorted(Comparator.comparingInt(e -> ((List<Integer>) e).get(0)).reversed()).findFirst().get();
}

public static void main(String[] args) throws IOException {
    System.out.println(highest_pair(1, 1, 2, 2, 3, 4, 5, 6));
}
```


Wieso ist dort ein Cast? ... Eclipse kann bei mir sonst damit nicht umgehen.


----------



## Tarrew (1. Sep 2019)

Tobias-nrw hat gesagt.:


> Wieso ist dort ein Cast? ... Eclipse kann bei mir sonst damit nicht umgehen.


Das hat nichts mit Eclipse zu tun.
So gehts ohne Cast:

```
public static List<Integer> highest_pair(int... a) {
    List<Integer> b = Arrays.stream(a).boxed().collect(Collectors.toList());
    return IntStream.range(0, a.length - 1).mapToObj(e -> b.subList(e, e + 2)).filter(e -> e.get(0) == e.get(1)).sorted(Comparator.comparingInt((List<Integer> e) -> e.get(0)).reversed()).findFirst().get();
}
```

oder noch besser so: 

```
public static List<Integer> highest_pair(int... a) {
    List<Integer> b = Arrays.stream(a).boxed().collect(Collectors.toList());
    return IntStream.range(0, a.length - 1).mapToObj(e -> b.subList(e, e + 2)).filter(e -> e.get(0).equals(e.get(1))).max(Comparator.comparingInt((List<Integer> e) -> e.get(0))).get();
}
```


----------



## Xyz1 (1. Sep 2019)

Tarrew hat gesagt.:


> Das hat nichts mit Eclipse zu tun


Stimmt, ist ein Bug von Java.


----------



## Xyz1 (1. Sep 2019)

Aber ehrlich... Das würde niemand jemals so schreiben.



Tarrew hat gesagt.:


> oder noch besser so


durch das max() ist es langsamer.


----------



## kneitzel (1. Sep 2019)

Also ich frage mich, was ihr da macht und baut. Und das dann als "die" Lösung zu bezeichnen und nicht als "eine" Lösung, bringt mich dann doch extrem zum Lachen.

Wieso nicht direkt auch a laufen? Warum muss das eine List sein? Und wenn ein Array gegeben wird: Wieso muss da dann ein List Element mit zwei Werten gegeben werden bei denen klar ist, dass die Werte in der List gleich sind?

Also wie man auf so einen Code kommt, kann ich nicht verstehen. Dabei muss man sich doch nur überlegen, wie man das ohne Streams machen würde. Da würde man über das Array iterieren und die Elemente vergleichen.

Daher würde dann bei mir etwas wie dies raus kommen:

```
import java.util.stream.IntStream;

public class StreamTest {

    public static Integer highestDoubleElementValue(int... a) {
        return a[IntStream
                .range(0, a.length - 1)
                .filter(e -> a[e] == a[e+1]).max().getAsInt()];
    }

    public static void main(String[] args) {
        System.out.println(highestDoubleElementValue(1, 1, 2, 2, 3, 4, 5, 6));
    }
}
```

Wobei ich nicht den Wert sondern den index zurück geben würde als Optional, das dann die Funktion tatsächlich zu einer einfach lesenden Zeile Code wird.


----------



## kneitzel (1. Sep 2019)

Und natürlich: das a[...] wandert noch in einen map Aufruf:

```
public static Integer highestDoubleElementValue(int... a) {
        return IntStream
                .range(0, a.length - 1)
                .filter(e -> a[e] == a[e+1])
                .map(e->a[e])
                .max()
                .getAsInt();
    }
```


----------



## Xyz1 (1. Sep 2019)

Hbx8x hat gesagt.:


> das doppelte höchste Paar angeben will, zb. das 8 das größte Paar ist


Also ich nehme an, er will dann auch ein Paar haben.

Deine "angebliche Lösung" funktioniert übrigens nicht... Setze doch mal 2, 2 nach vorne.


----------



## kneitzel (1. Sep 2019)

Also die Anforderung war, dass das Array sortiert ist. Aber selbst wenn es nicht sortiert ist, dann geht man halt her und mapt vor dem max(). 
Und wenn er ein Array hat, dann wird er wohl weniger einen List Eintrag haben wollen. Aber wenn: es ist wohl kein Problem, da eine kleine List mit zwei Mal dem Ergebnis zu erstellen... Aber: wenn die Anforderung nicht da ist, dann gilt: KISS: Keep It Simple & Stupid, also liefere das gesuchte doppelte Element bzw. den Wert daraus.

Und optimieren könnte man noch etwas: Und wenn es sortiert ist, dann nutzt man ein map ums rückwärts durch zu gehen um dann das erste Ergebnis zurück zu geben (da du ja die Performance erwähnt hattest.)

Ich habe halt nicht den Anspruch, ‚die‘ Lösung zu erstellen (das ist auch oft Ansichtssache) sondern ich will hier nur Aufzeigen, dass Deine Lösung eben aus meiner Sicht keine ist und Du alles zu kompliziert angegangen bist.


----------



## Xyz1 (1. Sep 2019)

kneitzel hat gesagt.:


> Also die Anforderung war, dass das Array sortiert ist


Nein, war es nicht, wäre es sortiert so stünden auch Nicht-Paare nebeneinander.



kneitzel hat gesagt.:


> dann geht man halt her und mapt vor dem max()


Was aber 0 bringt.

Also akzeptiere doch einfach mal das die beste Stream Lösung (sieht man von anderen Bibliotheken ab) durch mich gepostet wurde.


----------



## Xyz1 (1. Sep 2019)

Ok, vielleicht nicht die beste... Aber dann müsste erst eine bessere her. Vielleicht wüsste @Flown da etwas. 

Und wegen des Cast Bugs... Dieser tritt nur im Zusammenhang mit comparingInt() und reversed() auf. Lässt man das reversed() weg, so kann der Compiler das. Vielleicht kann da jemand eine Bug-Meldung erstellen, denn ich bin dort bislang nicht "in Erscheinung getreten".


----------



## temi (1. Sep 2019)

kneitzel hat gesagt.:


> Also die Anforderung war, dass das Array sortiert ist.





Tobias-nrw hat gesagt.:


> Nein, war es nicht





Hbx8x hat gesagt.:


> ...sotiere und zb die letzen zwei Felder vom sotierten Array...



Ich korrigiere mal die Rechtschreib-, bzw. Flüchtigkeitsfehler, damit es klarer wird:

...so*r*tiere und zb die letzen zwei Felder vom so*r*tierten Array...


----------



## Xyz1 (1. Sep 2019)

Also wenn ich es vorher sortiere, dann wüsste ich nicht, was es bringt, nach Pärchen zu suchen.


----------



## temi (1. Sep 2019)

Tobias-nrw hat gesagt.:


> Also wenn ich es vorher sortiere, dann wüsste ich nicht, was es bringt, nach Pärchen zu suchen.



Warum nicht?

Es geht um das wertmäßig größte Paar im sortierten Array und das kann an einer beliebigen Stelle im Array stehen.

Ganz abgesehen geht es hier um eine Aufgabe für einen Programmieranfänger.

Beiträge im Sinne von "Schaut mal wie geil ich bin und was ich für eine tolle Streamlösung habe" sind hier völlig fehl am Platz.


----------



## Xyz1 (1. Sep 2019)

temi hat gesagt.:


> Beiträge im Sinne von "Schaut mal wie geil ich bin und was ich für eine tolle Streamlösung habe" sind hier völlig fehl am Platz.


Das machen alle anderen doch auch ständig.

Bearbeitung: Ich habe mich sozusagen im Sinne der Sozialisation nur dem Umfeld angepasst.


----------



## temi (1. Sep 2019)

Tobias-nrw hat gesagt.:


> Das machen alle anderen doch auch ständig.



Dann wäre es ein Zeichen von geistiger Stärke es nicht auch zu tun, sondern sich, auch wenn es schwerfällt, auf das Niveau des Fragestellenden "herabzulassen".


----------



## kneitzel (1. Sep 2019)

Hbx8x hat gesagt.:


> wenn ich ein unsotiertes int[] unsortiertarray sotiere und zb die letzen zwei Felder vom sotierten Array int [] sotiertesarray ={......, 8, 8}das doppelte höchste Paar angeben will, zb. das 8 das größte Paar ist, wie kann man das realisieren?



Da schauen wir einmal, was der TE geschrieben hat: er sortiert ein Array und will dann vom sortierten Array das höchste Paar, wobei er da dann sogar ein Beispiel bringt: 8. Also ein einzelner Wert.



Tobias-nrw hat gesagt.:


> Also wenn ich es vorher sortiere, dann wüsste ich nicht, was es bringt, nach Pärchen zu suchen.


Jetzt verarscht Du uns und stellst Dich dumm, oder? Dadurch stehen gleiche Werte beieinander.



Tobias-nrw hat gesagt.:


> Was aber 0 bringt.
> 
> Also akzeptiere doch einfach mal das die beste Stream Lösung (sieht man von anderen Bibliotheken ab) durch mich gepostet wurde.



Also da wollte ich jetzt einmal das Beispiel schreiben, dass bei unsortiertem Array dann den Wert vom höchsten Paar gibt, aber das habe ich ja schon gemacht. Die Version mit dem map(e->a[e]), die ich als zweites gepostet habe, sorgt ja schon dafür, dass das höchste Paar ausgegeben wird, auch wenn es nicht an letzter Stelle steht.

Oder wenn es um das letzte Pärchen geht (unabhängig vom Wert), dann gehe ich einfach von hinten und liefere das erste Ergebnis. (Also z.b. Mittels .range(....).map(e->Max-e)..... wobei Max noch entsprechend mit dem entsprechenden Wert ersetzt wird ....



temi hat gesagt.:


> Beiträge im Sinne von "Schaut mal wie geil ich bin und was ich für eine tolle Streamlösung habe" sind hier völlig fehl am Platz.


‚Tolle Streamlösung‘ ist gut. Ist ja toll, dass er sich an Streams ran traut, aber so geistige Ergüsse zu posten und zu glauben, dass es ‚die‘ Lösung ist, ist schon eine gute Leistung  wie sehr kann man sich selbst falsch sehen? Von so Dingen wie ‚Anforderung nicht gelesen oder nicht verstanden‘ mal abgesehen!


----------



## Xyz1 (1. Sep 2019)

kneitzel hat gesagt.:


> er sortiert ein Array


Das ist schon die erste Fehlinterpretation von Dir. Soll es erst sortiert werden, oder hat er es bereits sortiert? Das ist aufgrund der miesen Rechtschreibung noch völlig offen.

... Den Rest "deiner Ergüsse" lasse ich mal so stehen.


----------



## temi (1. Sep 2019)

Tobias-nrw hat gesagt.:


> Das ist schon die erste Fehlinterpretation von Dir. Soll es erst sortiert werden, oder hat er es bereits sortiert?



Es ist sortiert, denn aus `int[] unsortieresarray` wird  `int[] sortieresarray`.

Da bleibt wenig Interpretationsspielraum.


----------



## Xyz1 (1. Sep 2019)

Ja gut. Wenn Stream Lösungen nun/hierbei unangebracht sind, dann ignoriert bitte meinen Beitrag einfach.
Und außerdem... noch schönen Sonntag -.-


----------



## mrBrown (1. Sep 2019)

Die Lösung von @Tobias-nrw hat übrigens noch einen Bug, einfach mal mit einem Pärchen größer als 127 ausprobieren


----------



## kneitzel (1. Sep 2019)

Danke @mrBrown für das aufsplittern. Und damit ist es dann hier auch on Topic und wir können uns über Stream Lösungen für dieses Problem auslassen.


----------



## Xyz1 (1. Sep 2019)

mrBrown hat gesagt.:


> Die Lösung von @Tobias-nrw hat übrigens noch einen Bug,


Ich sach ja, kein Mensch würde das so schreiben.

Also, suchen wir nach allen Pärchen bei Beibehaltung der Reihenfolge (was für mich mehr Sinn macht, da man so aus der ursprünglichen Sequenz noch etwas ableiten könnte, zum Beispiel Erbgutfehler o.Ä. - wofür Streams aber wirklich viel zu viel Overhead hätten.)


----------



## kneitzel (1. Sep 2019)

Ja, so wie Du würde das niemand schreiben. Generell spricht aber nichts gegen die Streams api. Streams müssen auch nicht mehr Overhead haben. Sie können, aber müssen nicht, langsamer sein. Recht interessant ist z.B. https://blog.overops.com/benchmark-how-java-8-lambdas-and-streams-can-make-your-code-5-times-slower/

Da war das Ergebnis erst relativ fatal und dann würden halt Fehler eliminiert um dann am Ende die gleiche Performance zu haben....


----------



## Flown (1. Sep 2019)

Tobias-nrw hat gesagt.:


> Ok, vielleicht nicht die beste... Aber dann müsste erst eine bessere her. Vielleicht wüsste @Flown da etwas.


Die Anforderung war auf jedenfall bei einem sortierten Array das größte Paar zu suchen.
Ich würde auf jedenfall mit eine short-circuit arbeiten, um nicht alles zu durchlaufen:


```
import java.util.Arrays;
import java.util.OptionalInt;
import java.util.stream.IntStream;

public class App {

    public static void main(String... args) {
        highestPair(1, 1, 2, 2, 2, 3, 4, 5, 6).ifPresentOrElse(
                i -> System.out.format("Highest pair is: %d%n", i),
                () -> System.out.println("No pair present")
        );
    }

    public static OptionalInt highestPair(int... a) {
        Arrays.sort(a);
        return IntStream.iterate(a.length - 1, i -> i > 0, i -> i - 1).filter(i -> a[i] == a[i - 1]).map(i -> a[i]).findFirst();
    }
}
```


----------



## Xyz1 (2. Sep 2019)

Wir müssen uns erst über die Anforderungen klar werden...

1. Zusatzzeile sort(),
2. kein sorted() im Stream,
3. OptionalInt statt nur ein int.

Das wären jetzt die Punkte welche mir aufgefallen sind und hier wäre mein Vorschlag:

```
public static OptionalInt highestPairUnsorted(int... a) {
	return IntStream.iterate(a.length - 1, i -> i > 0, i -> i - 1).filter(i -> a[i] == a[i - 1]).map(i -> a[i]).boxed()
			.sorted(Comparator.reverseOrder()).mapToInt(Integer::intValue)
			.findFirst();
}

public static OptionalInt highestPairSorted(int... a) {
	return IntStream.iterate(a.length - 1, i -> i > 0, i -> i - 1).map(i -> a[i]).boxed()
			.sorted(Comparator.reverseOrder()).filter(i -> a[i] == a[i - 1]).mapToInt(Integer::intValue)
			.findFirst();
}

public static void main(String[] args) throws IOException {
	System.out.println(highestPairUnsorted(2, 2, 1, 1, 3, 4, 5, 6, 3));
	System.out.println(highestPairSorted(2, 2, 1, 1, 3, 4, 5, 6, 3));
}
```


----------



## Xyz1 (2. Sep 2019)

Ich würd mich zur Übung der grauen Zellen auch noch für zwei Prolog (das ist der Dinosaurier...) Lösungen (... damit es richtig ineffizient wird ) interessieren. Wüsstet ihr da etwas?


----------



## kneitzel (2. Sep 2019)

Tobias-nrw hat gesagt.:


> (... damit es richtig ineffizient wird )


Also nach dem, was da in dem von mir geteilten Link steht, würde ich vermuten, dass Du da doch schon auf einem super Weg bist mit Deinem boxing ...

Ansonsten verstehe ich gerade nicht, welches Problem Du versuchst zu lösen, welches nicht prinzipiell schon gelöst wurde in dem Thread. Evtl. kannst Du es ja etwas ausformulieren, was Du da an Anforderungen siehst... Derzeit kann man da nur raten, was Du meinen könntest.


----------



## Xyz1 (2. Sep 2019)

kneitzel hat gesagt.:


> Evtl. kannst Du es ja etwas ausformulieren, was Du da an Anforderungen siehst


Nein. Das steht alles in diesem Thread. Ich bin für Analphabetismus nicht verantwortlich.


----------



## kneitzel (2. Sep 2019)

Tobias-nrw hat gesagt.:


> Nein. Das steht alles in diesem Thread. Ich bin für Analphabetismus nicht verantwortlich.


Schön, wie Du auf der Sachebene bleibst! Das zeugt von einer gefestigten Persönlichkeit .

Und nein, ich wollte Dich nicht für irgend einen Analphabetismus oder so verantwortlich machen. Alleine schon diese Beurteilung steht mir nicht zu. Du meinst also, deine Art und Weise liegt an einem Analphabetismus? Ich hätte eher vermutet, dass Du einfach zu ungenau liest und formulierst und einfach zu faul bist, nachzudenken. Aber ja - natürlich kann es sein, dass Du durchaus Zeit investiert hast, aber die gebrachten Einzelheiten einfach zu komplex waren. (Dafür würde auch sprechen, dass Du in dem anderen Thread extrem viel Erläuterungen gebraucht hast, bis Du das eigentliche Problem überhaupt verstanden hast, das ist schon richtig ... Und auch die Probleme mit einfachen Elektrotechnischen Grundlagen könnten darauf zurück zu führen sein ... also ja: durchaus möglich ...)

Aber ich will hier deinen Status nicht diskutieren, denn Deine Person ist hier nicht on topic. Wenn Du dies diskutieren willst oder uns da näheres mitteilen willst, dann mach dafür einen eigenen Thread in der Plauderecke auf (oder @mrBrown verschiebt dies direkt dahin...)

@mrBrown: Sorry, aber hin und wieder muss auch so eine Antwort mal sein. Er hat ja jetzt öfters drum gebettelt .


----------



## Xyz1 (2. Sep 2019)

@kneitzel Also Bitte beteilige dich on-topic oder gar nicht...


----------



## kneitzel (2. Sep 2019)

Tobias-nrw hat gesagt.:


> @kneitzel Also Bitte beteilige dich on-topic oder gar nicht...



Mein Hinweis bezüglich der Laufzeit Problematik war on Topic. Vielleicht willst Du ja doch einmal den Link aus #23 lesen oder schrieben, wieso diese Problematik auf Deine Lösung nicht zutrifft.

Meine Nachfrage zu deinem Post war on Topic. Evtl. willst Du da ja doch einmal sachlich antworten.

So ist für jeden klar erkenntlich, wer die Sachebene verlassen hat. Aber ich freue mich, dass Du zu dieser zurück kehren willst. Kleiner hilfreicher Tipp: Oft hilft es anderen eine Aussage zu verstehen, wenn diese in ganze, korrekten Sätzen vorgebracht werden. (Irgend wer hat hier im Thread bei einem Anderen Rechtschreibprobleme angemeckert ... Mangelhafte Grammatik ist beim Verständnis aber deutlich schlimmer als nur ein einfacher Tippfehler ... aber ja: sowas ist nicht on Topic...)

BTW: wenn du nichts on Topic beitragen willst, dann lass es doch bitte ganz.


----------



## Xyz1 (2. Sep 2019)

Deine Beiträge sind "fast gar nicht" on-topic. Schon seit zig Beiträgen nicht. Zu #23: Es steht völlig außer Frage, dass jede vernünftige, "normale" Implementierung schneller ist als mit Streams. Aber darum ging es hier gar nicht, das war jedem hier Beitragenden bereits bewusst. Deshalb versuche gar nicht erst, etwas rechtfertigen zu wollen, was schlicht nicht geht - sondern beteilige Dich lieber mit einer aus Deiner Sicht "besseren" Lösung. Wenn Du das nicht willst, gibt's immer noch die Möglichkeit, den Rand zu halten.


----------



## kneitzel (2. Sep 2019)

Hast Du den Link gelesen? Da haben Messungen etwas anderes ergeben - Natürlich unter der Voraussetzung, dass man Ahnung hat, was man macht (Was Du ganz offensichtlich nicht hast, sonst würdest Du nicht solchen Schrott-Code als "die Lösung" verkaufen)!

Und ganz offensichtlich war es nicht jedem bewusst: Sonst hätte ich sowas ja nicht gepostet. Wie wäre es mal mit Argumenten? Was ist denn bitte falsch bei den Fakten, die da im verlinkten Artikel gebracht wurde? Da wurde ja etwas getestet von Leuten ohne wirkliche Ahnung mit einem erstaunlichen Ergebnis. Und da wurde dann auch die Stream-Lösung angepasst und schon war das Timing gleich (incl. dem Vorschlag den Titel anzupassen zu "Wenn man keine Ahnung von Streams hat, dann sind Stream um den Faktor 5 langsamer".)

Und wie soll ich mich an einer besseren Lösung beteiligen, wenn Du Dir irgendwelche neuen Abhängigkeiten aus den Fingern saugst ohne diese sauber zu dokumentieren? Dein Code "smells". Ich bin sicher, dass es relativ trivial ist, optimaleren Code zu schreiben, der schneller laufen wird und auch besser lesbar sein dürfte.

Aber Du bist ja noch nicht einmal bereit, Deine relativ cryptischen Aussagen zu erläutern. Du scheinst da mit einer Methode auf sortierte Arrays aufsetzen zu wollen, aber im Test übergibst Du kein sortiertes Array. Und ich frage da einfach nur nach und du kommst mit Analphabetismus um die Ecke. Vermutlich nur, weil ich gewagt habe, Deinen Code zu kritisieren, denn der geteilte Link beschreibt ein Problem: unnötiges Boxing als Grund für Performanceverlust. Ja, hast Du nicht gelesen oder nicht verstanden. Ist ja auch in Ordnung. Musst Du nicht. Aber sachliche Kritik an Deinem Code so persönlich zu nehmen und dann so zu reagieren ist kindisch und einfach falsch am Platz.

Also erläutere, was denn da nun die genauen neuen Anforderungen sind, und dann bekommst Du auch eine optimierte Stream Lösung!


----------



## Xyz1 (2. Sep 2019)

Unterstelle mir nicht so einen Blödsinn...

Das die Lösung in Deinen Augen unschön ist, liegt an Java, nicht an mir. Dass das boxed() langsam ist genauso.

Bleibt unterm Strich wieder nur zu sagen, dass von Dir wieder nur i ein längerer Text, aber ohne Inhalt kam.

Such Dir andere Themen und lass dieses intakt. Danke.


----------



## Flown (2. Sep 2019)

Tobias-nrw hat gesagt.:


> public static OptionalInt highestPairSorted(int... a) { return IntStream.iterate(a.length - 1, i -> i > 0, i -> i - 1).map(i -> a_).boxed() .sorted(Comparator.reverseOrder()).filter(i -> a == a[i - 1]).mapToInt(Integer::intValue) .findFirst(); }_


Gib mal zu deinem Test noch eine 100 dazu ins array. Die pipeline ist leider verbugt.


----------



## Xyz1 (2. Sep 2019)

Flown hat gesagt.:


> Die pipeline ist leider verbugt





(Es sind ja auch Streams... )


----------



## kneitzel (2. Sep 2019)

Tobias-nrw hat gesagt.:


> Unterstelle mir nicht so einen Blödsinn...
> 
> Das die Lösung in Deinen Augen unschön ist, liegt an Java, nicht an mir. Dass das boxed() langsam ist genauso.
> 
> ...


Ok, Dir ist bekannt, dass Deine Lösung nicht optimal ist.
Aber dennoch hälst Du diese immer noch für gut oder findet keine Lösung, die ohne z.B, ein boxed() auskommen würde.

Und wenn meine Texte für Dich keinen Inhalt haben, dann hast Du ein offensIchtliches Problem, einfache Texte zu verstehen. Aber mir wird das hier zu blöd. Ich muss meine Zeit nicht mir jemandem verbringen, der seine ersten Schritte mit Streams macht und dabei nur Quatsch verzapft....


----------



## Xyz1 (2. Sep 2019)

kneitzel hat gesagt.:


> Ich muss meine Zeit nicht ... verbringen ...



Ich würd ja sagen, Einsicht ist der erste Weg der Besserung... Aber das spare ich mir. Du unterschätzt mit Deinem Gehabe Deine Gesprächspartner, das ist einfach das Problem.

@Flown Danke für den Hinweis.


----------



## Flown (2. Sep 2019)

Next shot: Ohne Sortierfunktion und mit ein wenig Compilertrickserei und auch bereit für parallel Streams:


```
public static OptionalInt highestPair(int... a) {
    return Arrays.stream(a).collect(() -> new Object() {
        Set<Integer> seen = new HashSet<>();
        OptionalInt highest = OptionalInt.empty();
    }, (acc, i) -> {
        if(!acc.seen.add(i)) {
            acc.highest = OptionalInt.of(Math.max(i, acc.highest.orElse(i)));
        }
    }, (result, disposable) -> {
        for (Integer elem : disposable.seen) {
            if (!result.seen.add(elem)) {
                result.highest = OptionalInt.of(Math.max(elem, disposable.highest.orElse(elem)));
            }
        }
        result.highest = result.highest.isEmpty() && disposable.highest.isEmpty() ? result.highest : OptionalInt.of(Math.max(disposable.highest.orElseGet(result.highest::getAsInt), result.highest.orElseGet(disposable.highest::getAsInt)));
    }).highest;
}
```


----------



## Der Wissende (2. Sep 2019)

Wie ist denn das mit dem sortiert gemeint? Was ich meine, müssen in der ursprünglichen Menge schon die Päärchen neben einander stehen oder können durch die Sortierung neue Päärchen entstehen?

Also ist bei `4, 4, 7, 7, 1, 2, 3, 3, 8 , 5, 8` die Lösung 7weil im Ursprungsarry nur die 7 schon als Paar auftritt oder die 8 weil nach dem sortieren dann ein neues Paar 8 entsteht?

Für den ersten Fall haben wir, soweit ich sehe, noch keine direkte Lösung, es ginge die von @Flown  noch mit einem zusätzlichen Sortier-schritt.

Für den 2. Fall würde ich mal diese hier ins Rennen schicken, weil dann wäre die Frage ja welche ist die größte Zahl, die öfter als einmal vorkommt, und so könnte man sich das ganze sortieren sparen.


```
public static int highestPair(int... values) {
        Set<Integer> seen = new HashSet<>();
        return IntStream.of(values)
                .reduce(0, (a, b) -> {
                    if (b > a && seen.contains(b)) {
                        return b;
                    } else {
                        seen.add(b);
                        return a;
                    }
                });
    }
```


----------



## Xyz1 (2. Sep 2019)

Das ist ja alles schön, aber nur noch halb funktional.

Desweiteren


Der Wissende hat gesagt.:


> Für den ersten Fall haben wir, soweit ich sehe, noch keine direkte Lösung


Du kannst aber doch lesen oder?


----------



## Der Wissende (2. Sep 2019)

Tobias-nrw hat gesagt.:


> Das ist ja alles schön, aber nur noch halb funktional.


Weil ich außerhalb einen  State halte. Ja das stimmt. Aber es geht ja hier um Streams und nicht funktional nach Lehrbuch oder?



Tobias-nrw hat gesagt.:


> Du kannst aber doch lesen oder?


Dir ist schon klar, dass deine Lösung nur recht zufällig die 7 für meinen input ausspuckt und weshalb die 100 einen Fehler verursacht? Ich hab es mal als Kommentar in deinen Code geschrieben.


```
public static OptionalInt highestPairSorted(int... a) {
    return IntStream.iterate(a.length - 1, i -> i > 0, i -> i - 1)
            .map(i -> a[i])
            .boxed()
            .sorted(Comparator.reverseOrder())
            //i ist hier nicht mehr der index, wie oben, sondern die eigentliche Zahl.
            //daher kracht es auch, wenn du 100 eingibst, das hat nix mit streams zu tun
            //Es funktioniert solange i < a.length ist, aber das Ergebnis ist eher zufällig.
            .filter(i -> a[i] == a[i - 1])
            .mapToInt(Integer::intValue)
            .findFirst();
}
```

Edit: Deine erste Lösung könnte das machen, wenn Du noch den Bug den @mrBrown schon genannt hat, ausbaut. Insofern haben wir noch keine funktionierende Lösung.


----------



## Xyz1 (2. Sep 2019)

Ja stimmt Sorry dann habe ich Streams umsonst verdächtigt...

Welche erst Lösung meinst du denn jetzt? Die aus #1?


----------



## Der Wissende (2. Sep 2019)

Tobias-nrw hat gesagt.:


> Welche erst Lösung meinst du denn jetzt? Die aus #1


Ja die mein ich, da hast du noch das Problem das `filter(e -> e.get(0) == e.get(1))` Integer-Referenzen vergleicht, aber das geht nur gut bis 127, weil die ersten 127 Elemente gecached sind, danach wird ein `new Integer(128)` gemacht.


----------



## Xyz1 (2. Sep 2019)

Ich habe (beides) mal verbessert:


```
@SuppressWarnings("unchecked")
	public static List<Integer> highest_pair(int... a) {
		List<Integer> b = Arrays.stream(a).boxed().collect(Collectors.toList());
		return IntStream.range(0, a.length - 1).mapToObj(e -> b.subList(e, e + 2)).filter(e -> e.get(0) == e.get(1))
				.sorted(Comparator.comparingInt(e -> ((List<Integer>) e).get(0)).reversed()).findFirst().get();
	}

	public static OptionalInt highest_pair_sorted(int... a) {
		return IntStream.range(0, a.length - 1).filter(i -> Arrays.stream(a).filter(j -> a[i] == j).count() >= 2).map(i -> a[i])
				.boxed().sorted(Comparator.reverseOrder()).mapToInt(Integer::intValue).findFirst();
	}

	public static void main(String[] args) throws IOException {
		System.out.println(highest_pair(2, 2, 1, 1, 3, 4, 5, 6, 3, 999));
		System.out.println(highest_pair_sorted(2, 2, 1, 1, 3, 4, 5, 6, 3, 999));
	}
```




Der Wissende hat gesagt.:


> aber das geht nur gut bis 127, weil die ersten 127 Elemente gecached sind, danach wird ein `new Integer(128)` gemacht



Wie umgehe ich das?

Bearbeitung:

```
return IntStream.range(0, a.length - 1).mapToObj(e -> b.subList(e, e + 2)).filter(e -> e.get(0).equals(e.get(1)))
				.sorted(Comparator.comparingInt(e -> ((List<Integer>) e).get(0)).reversed()).findFirst().get();
```


----------



## Der Wissende (2. Sep 2019)

Tobias-nrw hat gesagt.:


> Wie umgehe ich das?


Das Problem entsteht durch das `boxed()` was intern wieder `Integer::valueOf` aufruft, und das wiederum verwendet den Cache. Umgehen kannst du es in dem du equals zum Vergleichen verwendest. Oder du arbeitest mit arrays statt Listen, dann hast du das Problem auch nicht. 

Das könnte ungefähr so aussehen:



```
public static int highestPairSorted(int... values) {
        if (values.length == 1) {
            return values[0];
        }
        return IntStream.iterate(0, i -> i < values.length - 2, i -> i + 1)
                .mapToObj(i -> new int[]{values[i], values[i + 1]})
                .filter(p -> p[0] == p[1])
                .mapToInt(p -> p[0])
                .sorted()
                .reduce(0, (a, b) -> b);
    }
```

Du hast übrigens auch noch das Problem in deinem Code, wenn nur ein Element übergeben wird.


----------



## Xyz1 (2. Sep 2019)

Der Wissende hat gesagt.:


> Du hast übrigens auch noch das Problem in deinem Code, wenn nur ein Element übergeben wird


Na, bei einem Element erwarte ich wie bereits richtig bei ersterem eine NoSuchElementException und bei zweiterem ein OptionalInt.empty, da es kein Pärchen gibt.



Der Wissende hat gesagt.:


> i -> new int[]{values_, values[i + 1]}_


So richtig "optimal" ist das auch nicht.


----------



## Xyz1 (3. Sep 2019)

Moooin,


Tobias-nrw hat gesagt.:


> e.get(0) == e.get(1)


bei mir tritt dieser Fehler nicht auf.


----------



## Der Wissende (3. Sep 2019)

Tobias-nrw hat gesagt.:


> Na, bei einem Element erwarte ich wie bereits richtig bei ersterem eine NoSuchElementException und bei zweiterem ein OptionalInt.empty, da es kein Pärchen gibt.



Deine eine Lösung wirft nur im Falle das keine Päärchen vorhanden sind eine NoSuchElementException, im Falle wenn nur ein Element übergeben wird eine IndexOutOfBoundsException. Das finde ich jetzt nicht so schön, dass 2 verschiedene Exceptions geworfen werden.

Aber du hast Recht, meine Lösung hat gar keine Fehlerbehandlung. Hier nochmal eine angepasste Version:


```
public static OptionalInt highestPairSorted(int... values) {
        if (values.length == 1) {
            return OptionalInt.empty();
        }
        return IntStream.iterate(0, i -> i < values.length - 2, i -> i + 1)
                .mapToObj(i -> new int[]{values[i], values[i + 1]})
                .filter(p -> p[0] == p[1])
                .mapToInt(p -> p[0])
                .sorted()
                .reduce((a, b) -> b);
}
```




Tobias-nrw hat gesagt.:


> So richtig "optimal" ist das auch nicht.


Was gefällt dir daran nicht?



Tobias-nrw hat gesagt.:


> bei mir tritt dieser Fehler nicht auf.



Ich bekomm für:

```
System.out.println(highest_pair(12,33,300,300));
```

eine NoSuchElementException mit deinem Code von oben. Wenn ich == duch equals ersetzte bekomm ich 300.


----------



## Xyz1 (3. Sep 2019)

Mist, das passiert bei mir auch, das hätte mir doch eigentlich auffallen sollen...








						Using == operator in Java to compare wrapper objects
					

I'm reading SCJP Java 6 by Kathy Sierra and Bert Bates and this book is confusing me so much. On page 245 they state that the following code below.  Integer i1 = 1000; Integer i2 = 1000; if(i1 != i2)




					stackoverflow.com
				




Hier nochmal zwei "finale" Versionen:

```
public static Optional<List<Integer>> highest_pair_unsorted_1(int... a) {
	List<Integer> b = Arrays.stream(a).boxed().collect(Collectors.toList());
	return IntStream.range(0, a.length - 1).mapToObj(e -> b.subList(e, e + 2)).filter(e -> e.get(0).intValue() == e.get(1).intValue()).max(Comparator.comparingInt(e -> e.get(0)));
}

public static OptionalInt highest_pair_sorted_1(int... a) {
	return IntStream.range(0, a.length - 1).filter(i -> Arrays.stream(a).filter(j -> a[i] == j).count() >= 2).map(i -> a[i]).max();
}

public static void main(String[] args) throws IOException {
	System.out.println(highest_pair_unsorted_1(2, 2, 1, 1, 3, 4, 5, 6, 3, 999));
	System.out.println(highest_pair_sorted_1(2, 2, 1, 1, 3, 4, 5, 6, 3, 999));
	System.out.println(highest_pair_unsorted_1(1, 2, 3, 4, 999, 999));
	System.out.println(highest_pair_sorted_1(1, 2, 3, 4, 999, 999));
}
```


Wär das jetzt besser?


----------



## Xyz1 (3. Sep 2019)

Sind ein doppeltes Paar nicht eigentlich midestens 4 Elemente?, dann wäre der Thementitel doch falsch...


----------

