τα στοιχεία επικοινωνίας μου
Ταχυδρομείο[email protected]
2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
Η Java 8 εισάγει πολλά νέα χαρακτηριστικά, τα πιο αξιοσημείωτα από τα οποία είναι οι εκφράσεις Lambda και το Stream API. Το Stream API παρέχει μια αποτελεσματική και συνοπτική μέθοδο επεξεργασίας δεδομένων συλλογής, καθιστώντας τον κώδικα πιο συνοπτικό και σαφή και έχει υψηλή αναγνωσιμότητα και δυνατότητα συντήρησης. Αυτό το άρθρο θα εμβαθύνει στη χρήση του Java Stream API, συμπεριλαμβανομένων βασικών εννοιών, κοινών λειτουργιών, παράλληλης επεξεργασίας, πρακτικών περιπτώσεων και βέλτιστων πρακτικών.
Το Stream API είναι μια αφαίρεση που εισήχθη στην Java 8 για την επεξεργασία δεδομένων συλλογής που επιτρέπει την επεξεργασία δεδομένων με δηλωτικό τρόπο (παρόμοιο με τις δηλώσεις SQL). Το Stream API παρέχει πολλές ισχυρές λειτουργίες που μπορούν να χρησιμοποιηθούν για φιλτράρισμα, ταξινόμηση, χαρτογράφηση, μείωση και άλλες λειτουργίες σε συλλογές, απλοποιώντας σημαντικά τον κώδικα.
Το Stream API παρέχει μια ποικιλία τρόπων για τη δημιουργία μιας ροής, όπως οι παρακάτω:
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
String[] array = {"a", "b", "c"};
Stream<String> stream = Arrays.stream(array);
Stream.of
:Stream<String> stream = Stream.of("a", "b", "c");
Stream.generate
:Stream<Double> stream = Stream.generate(Math::random).limit(10);
Stream.iterate
:Stream<Integer> stream = Stream.iterate(0, n -> n + 2).limit(10);
Οι ενδιάμεσες λειτουργίες χρησιμοποιούνται για τη μετατροπή της ροής και αξιολογούνται νωχελικά.
filter
: χρησιμοποιείται για το φιλτράρισμα στοιχείων.Stream<String> stream = list.stream().filter(s -> s.startsWith("a"));
map
: Χρησιμοποιείται για την αντιστοίχιση κάθε στοιχείου στο αντίστοιχο αποτέλεσμα.Stream<String> stream = list.stream().map(String::toUpperCase);
flatMap
: Χρησιμοποιείται για τη μετατροπή κάθε στοιχείου σε ροή και στη συνέχεια τη συγχώνευσή του σε μία ροή.Stream<String> stream = list.stream().flatMap(s -> Stream.of(s.split("")));
distinct
: Χρησιμοποιείται για την αφαίρεση διπλότυπων.Stream<String> stream = list.stream().distinct();
sorted
: χρησιμοποιείται για ταξινόμηση.Stream<String> stream = list.stream().sorted();
peek
: Χρησιμοποιείται για την προβολή κάθε στοιχείου κατά την επεξεργασία.Stream<String> stream = list.stream().peek(System.out::println);
Οι λειτουργίες τερματικού χρησιμοποιούνται για την έναρξη του υπολογισμού της ροής και τη δημιουργία αποτελεσμάτων Οι συνήθεις λειτουργίες τερματικού περιλαμβάνουν τα ακόλουθα:
forEach
: Εκτελέστε μια λειτουργία σε κάθε στοιχείο.list.stream().forEach(System.out::println);
collect
: Μετατροπή ροής σε άλλες μορφές.List<String> result = list.stream().collect(Collectors.toList());
reduce
: Μειώστε τα στοιχεία στη Ροή σε τιμή.Optional<String> result = list.stream().reduce((s1, s2) -> s1 + s2);
toArray
:Μετατροπή ροής σε πίνακα.String[] array = list.stream().toArray(String[]::new);
count
: Μετρήστε τον αριθμό των στοιχείων.long count = list.stream().count();
anyMatch
、allMatch
、noneMatch
: Χρησιμοποιείται για αντιστοίχιση κρίσης.boolean anyMatch = list.stream().anyMatch(s -> s.startsWith("a"));
boolean allMatch = list.stream().allMatch(s -> s.startsWith("a"));
boolean noneMatch = list.stream().noneMatch(s -> s.startsWith("a"));
findFirst
、findAny
: Χρησιμοποιείται για την εύρεση στοιχείων.Optional<String> first = list.stream().findFirst();
Optional<String> any = list.stream().findAny();
χρήσηsorted
Η μέθοδος ταξινομεί τη ροή και μπορεί να περάσει σε έναν συγκριτικό.
List<String> list = Arrays.asList("b", "c", "a");
List<String> sortedList = list.stream().sorted().collect(Collectors.toList());
// 逆序排序
List<String> sortedListDesc = list.stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
χρήσηfilter
Μέθοδος φιλτραρίσματος στοιχείων στη ροή.
List<String> list = Arrays.asList("a", "b", "c");
List<String> filteredList = list.stream().filter(s -> s.startsWith("a")).collect(Collectors.toList());
χρήσηmap
Η μέθοδος αντιστοιχίζει στοιχεία στη Ροή.
List<String> list = Arrays.asList("a", "b", "c");
List<String> mappedList = list.stream().map(String::toUpperCase).collect(Collectors.toList());
χρήσηreduce
Μέθοδος μείωσης των στοιχείων στο Stream.
List<String> list = Arrays.asList("a", "b", "c");
String result = list.stream().reduce("", (s1, s2) -> s1 + s2);
χρήσηcollect
Οι μέθοδοι μετατρέπουν τη ροή σε άλλες μορφές.
List<String> list = Arrays.asList("a", "b", "c");
List<String> collectedList = list.stream().collect(Collectors.toList());
Set<String> collectedSet = list.stream().collect(Collectors.toSet());
String joinedString = list.stream().collect(Collectors.joining(","));
Το Parallel Stream μπορεί να αξιοποιήσει πλήρως τα πλεονεκτήματα των πολυπύρηνων CPU για τη βελτίωση της αποτελεσματικότητας της επεξεργασίας δεδομένων.μπορεί να χρησιμοποιηθείparallelStream
Η μέθοδος δημιουργεί παράλληλη ροή.
List<String> list = Arrays.asList("a", "b", "c");
List<String> parallelList = list.parallelStream().map(String::toUpperCase).collect(Collectors.toList());
Μπορεί επίσης να χρησιμοποιηθείparallel
Η μέθοδος μετατρέπει μια κανονική ροή σε μια παράλληλη ροή.
List<String> list = Arrays.asList("a", "b", "c");
List<String> parallelList = list.stream().parallel().map(String::toUpperCase).collect(Collectors.toList());
Πρέπει να σημειωθεί ότι η παράλληλη ροή δεν είναι πάντα ταχύτερη από τη σειριακή ροή και πρέπει να ελεγχθεί ανάλογα με τη συγκεκριμένη κατάσταση.
Δεδομένης μιας συλλογής συμβολοσειρών, φιλτράρετε τις συμβολοσειρές των οποίων το μήκος είναι μικρότερο από 3 και μετατρέψτε τις υπόλοιπες συμβολοσειρές σε κεφαλαία.
List<String> list = Arrays.asList("a", "ab", "abc", "abcd");
List<String> result = list.stream()
.filter(s -> s.length() >= 3)
.map(String::toUpperCase)
.collect(Collectors.toList());
System.out.println(result); // 输出:[ABC, ABCD]
Δεδομένου ενός συνόλου ακεραίων, υπολογίστε τον μέσο όρο όλων των ακεραίων.
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
OptionalDouble average = list.stream()
.mapToInt(Integer::intValue)
.average();
average.ifPresent(System.out::println); // 输出:3.0
Χρήση του Stream API
Διαβάστε τα περιεχόμενα του αρχείου και βγείτε στην κονσόλα.
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
Διαβάστε τα περιεχόμενα του αρχείου και μετρήστε τον αριθμό των εμφανίσεων κάθε λέξης.
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
Map<String, Long> wordCount = lines
.flatMap(line -> Arrays.stream(line.split("\W+")))
.collect(Collectors.groupingBy(String::toLowerCase, Collectors.counting()));
wordCount.forEach((word, count) -> System.out.println(word + ": " + count));
} catch (IOException e) {
e.printStackTrace();
}
Ας υποθέσουμε ότι έχουμε έναν πίνακα βάσης δεδομένωνusers
, που περιέχει πεδίαid
、name
καιage
. Μπορούμε να χρησιμοποιήσουμε το Stream API για να επεξεργαστούμε τα αποτελέσματα του ερωτήματος.
List<User> users = queryDatabase();
List<String> names = users.stream()
.filter(user -> user.getAge() > 18)
.map(User::getName)
.collect(Collectors.toList());
System.out.println(names);
Collectors
Η τάξη παρέχει μια ποικιλία συλλεκτών και μπορείτε να επιλέξετε τον κατάλληλο συλλέκτη ανάλογα με τις συγκεκριμένες ανάγκες.Μόλις καταναλωθεί μια ροή, δεν μπορεί να χρησιμοποιηθεί ξανά, εάν πρέπει να την επαναχρησιμοποιήσετε, μπορείτε να εξετάσετε το ενδεχόμενο μετατροπής της ροής σε συλλογή πριν τη χρησιμοποιήσετε.
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
stream.forEach(System.out::println); // 会抛出IllegalStateException
Οι παράλληλες ροές δεν είναι πάντα ταχύτερες από τις σειριακές ροές και πρέπει να ελέγχονται κατά περίπτωση.μπορεί να χρησιμοποιηθείForkJoinPool
Για τη βελτιστοποίηση της απόδοσης της παράλληλης ροής.
ForkJoinPool customThreadPool = new ForkJoinPool(4);
customThreadPool.submit(() ->
list.parallelStream().forEach(System.out::println)
).get();
Όταν χρησιμοποιείτε το Stream API για την επεξεργασία μεγάλων ποσοτήτων δεδομένων, πρέπει να δώσετε προσοχή στο πρόβλημα των διαρροών μνήμης.μπορεί να χρησιμοποιηθείclose
μέθοδος για να κλείσετε τη ροή ή να χρησιμοποιήσετεtry-with-resources
δήλωση κλείνει αυτόματα τη ροή.
try (Stream<String> lines = Files.lines(Paths.get("example.txt"))) {
lines.forEach(System.out::println);
} catch (IOException e) {
e.printStackTrace();
}
Αυτό το άρθρο εισάγει λεπτομερώς τη χρήση του Java Stream API, συμπεριλαμβανομένων βασικών λειτουργιών, προηγμένων λειτουργιών, παράλληλης επεξεργασίας, πρακτικών περιπτώσεων και βέλτιστων πρακτικών. Χρησιμοποιώντας ορθολογικά το Stream API, οι προγραμματιστές μπορούν να απλοποιήσουν σημαντικά τον κώδικα, να βελτιώσουν την αναγνωσιμότητα και τη δυνατότητα συντήρησης του κώδικα και επίσης να βελτιώσουν την αποτελεσματικότητα της επεξεργασίας δεδομένων. Ελπίζω ότι αυτό το άρθρο θα σας βοηθήσει στη χρήση του Stream API στην ανάπτυξη Java.
Το Java Stream API είναι ένα ισχυρό εργαλείο για την επεξεργασία δεδομένων συλλογής Μέσω της ευέλικτης χρήσης διαφόρων λειτουργιών, μπορεί να επιτευχθεί αποτελεσματική επεξεργασία δεδομένων και υπολογιστική ροή. Εάν δεν έχετε χρησιμοποιήσει το Stream API, συνιστάται να μάθετε και να κυριαρχήσετε αυτό το ισχυρό εργαλείο το συντομότερο δυνατό και να το εφαρμόσετε στο έργο σας για να βελτιώσετε την αποτελεσματικότητα ανάπτυξης και την ποιότητα του κώδικα.