# Sådan bruges Java collect() til at indsamle og behandle data

Stream Collectors er en kraftfuld funktion i **Java 8 Stream API**, der giver dig mulighed for at indsamle og behandle data effektivt. Her forklarer vi deres struktur og hvordan Java collect()-metoden kan bruges.

## Hvordan kan Java collect() bruges?

En Stream Collector kan bruges til at oprette en liste, et sæt eller et kort fra en strøm. En strøm er en sekvens af elementer, der behandles efter hinanden. Collector-grænsefladen indeholder et sæt **reduktionsoperationer** til data i en strømpipeline. Dette er terminale operationer, der samler og fletter resultaterne af mellemliggende trin.

Collectors kan bruges til at filtrere eller sortere objekter fra en strøm. **Aggregering** er også mulig, f.eks. at summere tal, kombinere strenge eller tælle elementer. Derudover har Collectors funktioner, der kan omdanne indholdet af en strøm til en bestemt struktur. Du kan f.eks. omdanne en liste til et kort. Grupperinger hjælper med at kategorisere elementer med bestemte egenskaber eller betingelser. Vigtigst af alt har stream-samlere den fordel, at de kan **behandle data på samme tid** ved hjælp af flere tråde. Dette gør det muligt at udføre operationer meget hurtigere og mere effektivt, især med store datamængder.

## Hvad er syntaksen for Java collect()?

Metoden accepterer en Collector, der beskriver, hvordan elementerne i strømmen skal indsamles og aggregeres, som et argument. En **Collector er en grænseflade**, der tilbyder forskellige metoder til at aggregere strømelementer i en bestemt form, for eksempel i en liste, et sæt eller et kort.

Der findes to varianter af Java Stream-metoden collect():

1. R collect(Supplier&lt;R&gt; leverandør, BiConsumer&lt;R, ? super T&gt; akkumulator,BiConsumer&lt;R, R&gt; kombiner)
2. &lt;R, A&gt; R collect(Collector&lt;? super T, A, R&gt; collector)

Den første variant har tre funktioner som argumenter:

- **leverandør**: opretter en container, der vil blive brugt til mellemresultater
- **akkumulator**: beregner det endelige resultat
- **kombinator**: kombinerer resultaterne af parallelle strømoperationer

Disse foruddefinerede Collectors er allerede inkluderet i standardbiblioteket og kan nemt importeres og bruges.

Den anden variant accepterer en Collector som argument og returnerer et resultat.

- **R**: typen af resultat
- **T**: typen af elementer i strømmen
- **A**: typen af akkumulator, der gemmer den mellemliggende tilstand af collector-operationen
- **collector**: udfører reduktionsoperationen.

Ved at bruge denne variant kan udviklere oprette **tilpassede Collectors**, der er skræddersyet til deres behov og giver større fleksibilitet og kontrol over reduktionsprocessen.

## Hvad er nogle praktiske eksempler på brug af Java collect()?

Nedenfor illustrerer vi forskellige funktioner i `Stream.collect()` oden. Du bør allerede være fortrolig med de grundlæggende Java-operatorer, inden du går i gang med **samlingsrammen**.

### Sammenkæd en liste med strenge

Med Java Collect() kan vi **sammenkæde** en liste med strenge for at få en ny streng:

```Java
List<String> letters = List.of("a", "b", "c", "d", "e");
// without combiner function
StringBuilder result = letters.stream().collect(StringBuilder::new, (x, y) -> x.append(y),
    (a, b) -> a.append(",").append(b));
System.out.println(result.toString());
// with combiner function
StringBuilder result1 = letters.parallelStream().collect(StringBuilder::new, (x, y) -> x.append(y),
    (a, b) -> a.append(",").append(b));
System.out.println(result1.toString());
```

Outputtet er:

```Java
abcde
a, b, c, d, e
```

I den første beregning blev der kun brugt én StringBuilder-instans, og der var ingen kombinationsfunktion. Derfor er resultatet `abcde`.

I det andet output flettede kombinatorfunktionen StringBuilder-instanserne sammen og adskilte dem med et komma.

### Saml elementer i en liste med toList()

Vi kan bruge funktionen `filter()` til at vælge bestemte elementer i en liste og derefter bruge `toList()` til at gemme dem i en ny liste.

```Java
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
List<Integer> oddNumbers = numbers.stream().filter(x -> x % 2 != 0).collect(Collectors.toList());
System.out.println(oddNumbers);
```

I den nye liste er der kun ulige tal:

```Java
[1, 3, 5, 7]
```

### Saml elementer i et sæt med toSet()

På samme måde kan vi vælge elementer og oprette et nyt sæt ud fra dem. Elementerne i et sæt **behøver ikke at være arrangeret i en bestemt rækkefølge**.

```Java
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
Set<Integer> evenNumbers = numbers.parallelStream().filter(x -> x % 2 == 0).collect(Collectors.toSet());
System.out.println(evenNumbers);
```

Dette viser resultatet:

```Java
[2, 4, 6]
```

### Saml elementer i et kort med toMap()

Et kort kan bruges sammen med Java collect() til at tildele en værdi til hver nøgle.

```Java
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
Map<Integer, String> mapEvenNumbers = numbers.parallelStream().filter(x -> x % 2 == 0)
    .collect(Collectors.toMap(Function.identity(), x -> String.valueOf(x)));
System.out.println(mapEvenNumbers);
```

I outputtet kan vi se, at hvert lige tal i inputtet har fået tildelt en værdi, der er identisk med det:

```Java
{2=2, 4=4, 6=6}
```

### Kombiner elementer i en streng med joining()

Metoden `joining()` kombinerer elementer i en strøm i den rækkefølge, de vises, og bruger **en separator til at adskille elementerne**. Separatoren overføres som et argument til `joining()`. Hvis der ikke er angivet nogen separator, bruger `joining()` den tomme streng `""`.

```Java
jshell> String result1 = Stream.of("a", "b", "c").collect(Collectors.joining());
jshell> String result2 = Stream.of("a", "b", "c").collect(Collectors.joining(",", "{", "}"));
```

Resultaterne er:

```Java
result1 ==> "abc"
result2 ==> "{a,b,c}"
```


This is a markdown version of: [https://www.ionos.com/da-dk/digitalguide/websteder/webudvikling/java-stream-collect/](https://www.ionos.com/da-dk/digitalguide/websteder/webudvikling/java-stream-collect/) for AI/LLM consumption.