
βμ΅λͺ ν΄λμ€λ (ν¨μν μΈν°νμ΄μ€κ° μλ) νμ μ μΈμ€ν΄μ€λ₯Ό λ§λ€ λλ§ μ¬μ©νλΌβ
// μ΅λͺ
ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό ν¨μ κ°μ²΄λ‘ μ¬μ© - λ‘μ κΈ°λ²μ΄λ€!
Collections.sort(words, new Comparator<String>() {
public int compare(String s1, String s2) {
return Integer.compare(s1.length(), s2.length());
}
});
System.out.println(words);
Collections.shuffle(words);
// μ½λ 42-2 λλ€μμ ν¨μ κ°μ²΄λ‘ μ¬μ© - μ΅λͺ
ν΄λμ€ λ체
Collections.sort(words,
(s1, s2) -> Integer.compare(s1.length(), s2.length()));
System.out.println(words);
Collections.shuffle(words);
DoubleBinaryOperator μΈν°νμ΄μ€ λ³μμ ν λΉν¨.DoubleBinaryOperator μΈν°νμ΄μ€λ double νμ
μΈμ 2κ°λ₯Ό λ°μ double νμ
κ²°κ³Όλ₯Ό λ°νν¨.// ν¨μ κ°μ²΄(λλ€)λ₯Ό μΈμ€ν΄μ€ νλμ μ μ₯ν΄ μμλ³ λμμ ꡬνν μ΄κ±° νμ
public enum Operation {
PLUS ("+", (x, y) -> x + y),
MINUS ("-", (x, y) -> x - y),
TIMES ("*", (x, y) -> x * y),
DIVIDE("/", (x, y) -> x / y);
private final String symbol;
private final DoubleBinaryOperator op;
Operation(String symbol, DoubleBinaryOperator op) {
this.symbol = symbol;
this.op = op;
}
@Override public String toString() { return symbol; }
public double apply(double x, double y) {
return op.applyAsDouble(x, y);
}
}
thisν€μλλ λ°κΉ₯ μΈμ€ν΄μ€, μ΅λͺ
ν΄λμ€μμμ thisλ μμ βλ©μλ μ°Έμ‘° μͺ½μ΄ μ§§κ³ λͺ ννλ€λ©΄ λ©μλ μ°Έμ‘°λ₯Ό μ°κ³ , κ·Έλ μ§ μμ λλ§ λλ€λ₯Ό μ¬μ©νλΌβ
// map.mergeλ₯Ό μ΄μ©ν΄ ꡬνν λΉλν - λλ€ λ°©μκ³Ό λ©μλ μ°Έμ‘° λ°©μμ λΉκ΅ν΄λ³΄μ.
public class Freq {
public static void main(String[] args) {
Map<String, Integer> frequencyTable = new TreeMap<>();
for (String s : args)
frequencyTable.merge(s, 1, (count, incr) -> count + incr); // λλ€
System.out.println(frequencyTable);
frequencyTable.clear();
for (String s : args)
frequencyTable.merge(s, 1, Integer::sum); // λ©μλ μ°Έμ‘°
System.out.println(frequencyTable);
}
}
| λ©μλ μ°Έμ‘° μ ν | μμ | λλ€ νν |
|---|---|---|
| μ μ | Integer::parseInt | str β Integer.parseInt(str) |
| νμ μ (μΈμ€ν΄μ€) | Instant.now()::isAfter | Instant then = Instant.now(); t β then.isAfter(t) |
| λΉνμ μ (μΈμ€ν΄μ€) | String::toLowerCase | str β str.toLowerCase() |
| ν΄λμ€ μμ±μ | TreeMap<K, V>::new | () β new TreeMap<K, V>() |
| λ°°μ΄ μμ±μ | int[]::new | len β new int[len] |
β보ν΅μ
java.util.functionν¨ν€μ§μ νμ€ ν¨μν μΈν°νμ΄μ€λ₯Ό μ¬μ©νλ κ²μ΄ κ°μ₯ μ’μ μ νβ
java.util.function ν¨ν€μ§λ₯Ό 보면 λ€μν μ©λμ νμ€ ν¨μν μΈν°νμ΄μ€κ° λ΄κ²¨ μμ.| μΈν°νμ΄μ€ | ν¨μ μκ·Έλμ² | μ | μ€λͺ |
|---|---|---|---|
| UnaryOperator | T apply(T t) | String::toLowerCase | λ°νκ°κ³Ό μΈμμ νμ μ΄ κ°μ ν¨μ(μΈμ 1κ°) |
| BinaryOperator | T apply(T t1, T t2) | BigInteger::add | λ°νκ°κ³Ό μΈμμ νμ μ΄ κ°μ ν¨μ(μΈμ 2κ°) |
| Predicate | boolean test(T t) | Collection::isEmpty | μΈμ νλλ₯Ό λ°μ booleanμ λ°ννλ ν¨μ |
| Function<T, R> | R apply(T t) | Arrays::asList | μΈμμ λ°ν νμ μ΄ λ€λ₯Έ ν¨μ |
| Supplier | T get() | Instance::now | μΈμλ₯Ό λ°μ§ μκ³ κ°μ λ°ν(νΉμ μ 곡)νλ ν¨μ |
| Consumer | void accept(T t) | System.out::println | μΈμλ₯Ό νλ λ°κ³ λ°νκ°μ μλ(νΉν μΈμλ₯Ό μλΉνλ ) ν¨μ |
Compartor<T> μΈν°νμ΄μ€ToIntBiFunction<T, U> μ λμΌν¨.@FunctionalInterface μ΄λ
Έν
μ΄μ
μ μ¬μ©νλΌ.@FunctionalInterface μ΄λ
Έν
μ΄μ
μ κΈ°λ₯βμ€νΈλ¦Όκ³Ό λ°λ³΅ μ€ μ΄λ μͺ½μ΄ λμμ§ νμ νκΈ° μ΄λ ΅λ€λ©΄ λ λ€ ν΄λ³΄κ³ λ λμ μͺ½μ ννλΌβ
// μ€νΈλ¦Όμ μ μ ν νμ©νλ©΄ κΉλνκ³ λͺ
λ£ν΄μ§λ€.
public class HybridAnagrams {
public static void main(String[] args) throws IOException {
Path dictionary = Paths.get(args[0]);
int minGroupSize = Integer.parseInt(args[1]);
try (Stream<String> words = Files.lines(dictionary)) {
words.collect(groupingBy(word -> alphabetize(word)))
.values().stream()
.filter(group -> group.size() >= minGroupSize)
.forEach(g -> System.out.println(g.size() + ": " + g));
}
}
private static String alphabetize(String s) {
char[] a = s.toCharArray();
Arrays.sort(a);
return new String(a);
}
}
CharSequence μΈν°νμ΄μ€μ chars() λ©μλλ λ°ν κ°μ΄ IntStream μ.finalμ΄κ±°λ μ¬μ€μ finalμΈ λ³μλ§ μ½μ μ μμ)return, break, continueλ¬Έ μ¬μ©. (λλ€μμλ λΆκ°λ₯)static Stream<BigInteger> primes() { ... }βμ€νΈλ¦Ό μ°μ°μ 건λ€λ ν¨μ κ°μ²΄λ λͺ¨λ λΆμμ©(side effect)μ΄ μμ΄μΌ νλ€β
forEach μ°μ°μ μ’
λ¨ μ°μ° μ€ κΈ°λ₯μ΄ κ°μ₯ μ κ³ κ°μ₯ βλβ μ€νΈλ¦Όλ€μ.β forEach μ°μ°μ μ€νΈλ¦Ό κ³μ° κ²°κ³Όλ₯Ό λ³΄κ³ ν λλ§ μ¬μ©νκ³ , κ³μ°νλ λ°λ μ°μ§ λ§μ.
java.util.stream.Collectors μ λ©€λ²λ₯Ό μ μ μν¬νΈνμ¬ μ¬μ©ν¨.toList() : 리μ€νΈ λ°ν// λΉλνμμ κ°μ₯ νν λ¨μ΄ 10κ°λ₯Ό λ½μλ΄λ νμ΄νλΌμΈ
List<String> topTen = freq.keySet().stream()
.sorted(comparing(freq::get).reversed())
.limit(10)
.collect(toList());
toMap(keyMapper, valueMapper) : ν€ λ§€νΌμ κ° λ§€νΌλ₯Ό λ°μ λ§΅μ λ°νMap<String, Operation> stringToEnum =
Stream.of(values()).collect(
toMap(Object::toString, e -> e));
toSet() : μ§ν© λ°νSet<String> result = givenList.stream()
.collect(toSet());
joining() : μμλ€μ μ°κ²°νμ¬ λ¬Έμμ΄ λ°ν// λ§€κ°λ³μκ° μμ κ²½μ° : "abbcccdd" μΆλ ₯
String result = givenList.stream()
.collect(joining());
// λ§€κ°λ³μκ° μμ κ²½μ°(ꡬλΆλ¬Έμλ₯Ό μ°κ²°λΆμμ μ½μ
ν΄ μ€) : "a bb ccc dd" μΆλ ₯
String result = givenList.stream()
.collect(joining(" "));
groupingBy(classifier) : λΆλ₯ ν¨μλ₯Ό λ§€κ°λ³μλ‘ λ°μ μμλ€μ μΉ΄ν
κ³ λ¦¬λ³λ‘ λͺ¨μ λμ λ§΅μ λ΄μ μμ§κΈ° λ°ν.// κ°λ¨ν μμ : μνλ²³νν λ¨μ΄λ₯Ό μνλ²³ν κ²°κ³Όκ° κ°μ λ¨μ΄λ€μ 리μ€νΈλ‘ λ§€ννλ λ§΅ μμ±.
private static String alphabetize(String s) {
char[] a = s.toCharArray();
Arrays.sort(a);
return new String(a);
}
words.collect(groupingBy(word -> alphabetize(word)));
// λΆλ₯ ν¨μμ λ€μ΄ μ€νΈλ¦Όμ λ°λ μμ
/** λ€μ΄μ€νΈλ¦Ό μμ§κΈ°λ‘ counting()μ 건λ€μ κ° μΉ΄ν
κ³ λ¦¬(ν€)λ₯Ό (μμλ₯Ό λ΄μ 컬λ μ
μ΄ μλ)
* ν΄λΉ μΉ΄ν
κ³ λ¦¬μ μνλ μμμ κ°μ(κ°)μ λ§€νν λ§΅μ μ»μ
*/
// μ€νΈλ¦Όμ μ λλ‘ νμ©ν΄ λΉλνλ₯Ό μ΄κΈ°ννλ€.
Map<String, Long> freq;
try (Stream<String> words = new Scanner(file).tokens()) {
freq = words
.collect(groupingBy(String::toLowerCase, counting()));
}
groupingBy λͺ
μΈstatic <T,K> Collector<T,?,Map<K,List<T>>>
groupingBy(Function<? super T,? extends K> classifier)
static <T,K,A,D> Collector<T,?,Map<K,D>>
groupingBy(Function<? super T,? extends K> classifier,
Collector<? super T,A,D> downstream)
static <T,K,D,A,M extends Map<K,D>> Collector<T,?,M>
groupingBy(Function<? super T,? extends K> classifier,
Supplier<M> mapFactory, Collector<? super T,A,D> downstream)
βμμ μνμ€λ₯Ό λ°ννλ κ³΅κ° APIμ λ°ν νμ μλ
Collectionμ΄λ κ·Έ νμ νμ μ μ°λ κ² μΌλ°μ μΌλ‘ μ΅μ β
for-eachλ‘ λ°λ³΅νκΈΈ μνλ μ¬μ©μλ λΆλ§μ ν λ‘ν κ²μ.Stream<E>λ₯Ό Iterable<E>λ‘ μ€κ°ν΄μ£Όλ μ΄λν°λ₯Ό μ¬μ©νλ©΄ μ€νΈλ¦Όμ for-eachλ¬ΈμΌλ‘ λ°λ³΅ν μ μμ// μ€νΈλ¦Ό <-> λ°λ³΅μ μ΄λν°
public class Adapters {
// Stream<E>λ₯Ό Iterable<E>λ‘ μ€κ°ν΄μ£Όλ μ΄λν°
public static <E> Iterable<E> iterableOf(Stream<E> stream) {
return stream::iterator;
}
// Iterable<E>λ₯Ό Stream<E>λ‘ μ€κ°ν΄μ£Όλ μ΄λν°
public static <E> Stream<E> streamOf(Iterable<E> iterable) {
return StreamSupport.stream(iterable.spliterator(), false);
}
}
Collection μΈν°νμ΄μ€λ Iterableμ νμ νμ
μ΄κ³ stream λ©μλλ μ 곡νλ λ°λ³΅κ³Ό μ€νΈλ¦Όμ λμμ μ§μν¨.β μμ μνμ€λ₯Ό λ°ννλ κ³΅κ° APIμ λ°ν νμ
μλ Collection μ΄λ κ·Έ νμ νμ
μ μ°λ κ² μΌλ°μ μΌλ‘ μ΅μ μ.
β ArrayListλ HashSet κ°μ νμ€ μ»¬λ μ
ꡬν체λ₯Ό λ°ννμ
β μ μ© μ»¬λ μ μ ꡬννλ λ°©μμ κ²ν ν΄λ³΄μ.
public class PowerSet {
// μ
λ ₯ μ§ν©μ λ©±μ§ν©μ μ μ© μ»¬λ μ
μ λ΄μ λ°ννλ€.
public static final <E> Collection<Set<E>> of(Set<E> s) {
List<E> src = new ArrayList<>(s);
if (src.size() > 30)
throw new IllegalArgumentException(
"μ§ν©μ μμκ° λ무 λ§μ΅λλ€(μ΅λ 30κ°).: " + s);
return new AbstractList<Set<E>>() {
@Override public int size() {
// λ©±μ§ν©μ ν¬κΈ°λ 2λ₯Ό μλ μ§ν©μ μμ μλ§νΌ κ±°λμ κ³± κ²κ³Ό κ°λ€.
return 1 << src.size();
}
@Override public boolean contains(Object o) {
return o instanceof Set && src.containsAll((Set)o);
}
@Override public Set<E> get(int index) {
Set<E> result = new HashSet<>();
for (int i = 0; index != 0; i++, index >>= 1)
if ((index & 1) == 1)
result.add(src.get(i));
return result;
}
};
}
public static void main(String[] args) {
Set s = new HashSet(Arrays.asList(args));
System.out.println(PowerSet.of(s));
}
}
containsμ sizeλ₯Ό ꡬννλ κ² λΆκ°λ₯ν λ(μ¦, 컬λ μ
μ λ°ννλ κ² λΆκ°λ₯ν λ)λ 컬λ μ
보λ€λ μ€νΈλ¦Όμ΄λ Iterableμ λ°ννλ νΈμ΄ λ«λ€.βκ³μ°λ μ¬λ°λ‘ μννκ³ μ±λ₯λ λΉ¨λΌμ§ κ±°λΌλ νμ μμ΄λ μ€νΈλ¦Ό νμ΄νλΌμΈ λ³λ ¬νλ μλμ‘°μ°¨ νμ§ λ§λΌβ
// λ³λ ¬ μ€νΈλ¦Όμ μ¬μ©ν΄ μ²μ 20κ°μ λ©λ₯΄μΌ μμλ₯Ό μμ±νλ νλ‘κ·Έλ¨
// μ£Όμ: λ³λ ¬νμ μν₯μΌλ‘ νλ‘κ·Έλ¨μ΄ μ’
λ£νμ§ μλλ€.
public class ParallelMersennePrimes {
public static void main(String[] args) {
primes().map(p -> TWO.pow(p.intValueExact()).subtract(ONE))
.parallel() // μ€νΈλ¦Ό λ³λ ¬ν
.filter(mersenne -> mersenne.isProbablePrime(50))
.limit(20)
.forEach(System.out::println);
}
static Stream<BigInteger> primes() {
return Stream.iterate(TWO, BigInteger::nextProbablePrime);
}
}
β μ€νΈλ¦Ό λΌμ΄λΈλ¬λ¦¬κ° μ΄ νμ΄νλΌμΈμ λ³λ ¬ννλ λ°©λ²μ μ°Ύμλ΄μ§ λͺ»νκΈ° λλ¬Έ.
Stream.iterate κ±°λ μ€κ° μ°μ°μΌλ‘ limitλ₯Ό μ°λ©΄ νμ΄νλΌμΈ λ³λ ¬νλ‘λ μ±λ₯ κ°μ μ κΈ°λν μ μμ.β μ μ½λλ λ λ¬Έμ λ₯Ό λͺ¨λ μ§λκ³ μμ..
β μ€νΈλ¦Ό λ³λ ¬νλ μ€μ§ μ±λ₯ μ΅μ ν μλ¨μμ κΈ°μ΅νμ. λ°λμ λ³κ²½ μ νλ‘ μ±λ₯ ν μ€νΈλ₯Ό μ§ννμ¬ λ³λ ¬νλ₯Ό μ¬μ©ν κ°μΉκ° μλμ§ λ°μ Έλ³΄μ.
ArrayList, HashMap, HashSet, ConcurrentHashMap μ μΈμ€ν΄μ€κ±°λ λ°°μ΄, int λ²μ, long λ²μμΌ λ μ ν©.Streamμ reduceλ©μλ μ€ νλ, νΉμ min, max, count, sum λ±anyMatch, allMatch, noneMatch λ±public class ParallelPrimeCounting {
// μμ κ³μ° μ€νΈλ¦Ό νμ΄νλΌμΈ - λ³λ ¬ν λ²μ
static long pi(long n) {
return LongStream.rangeClosed(2, n)
.parallel()
.mapToObj(BigInteger::valueOf)
.filter(i -> i.isProbablePrime(50))
.count();
}
public static void main(String[] args) {
System.out.println(pi(10_000_000));
}
}