Of: примеры (JAVA)

Обзор практических примеров метода of
Раздел: Время и дата (Date & Time API)
of(int year, int month, int dayOfMonth): LocalDate

Общее описание методов of в Java

В Java под именем of встречается множество статических фабричных методов в стандартной библиотеке. Основные группы: фабрики коллекций (List.of, Set.of, Map.of, Map.ofEntries), создание потоков и опциональных значений (Stream.of, Optional.of). Эти методы обычно предоставляют короткий синтаксис для создания экземпляров и часто возвращают неизменяемые (immutable) реализации.

Ниже перечислены ключевые варианты с описанием сигнатур, параметров и возвращаемых значений.

List.of(E... elements)

  • Аргументы: varargs элементов типа E. Поддерживает от 0 элементов и более.
  • Возвращаемое значение: экземпляр java.util.List, гарантированно неизменяемый. Реализация оптимизирована для небольшого числа элементов.
  • Особенности: не допускает null как элемент - при наличии null выбрасывает NullPointerException.

Set.of(E... elements)

  • Аргументы: varargs элементов. Поведение похоже на List.of.
  • Возвращаемое значение: неизменяемый Set. При попытке создать множество с дубликатами выбрасывается IllegalArgumentException.
  • Null-элементы запрещены.

Map.of() и Map.of(k1, v1, ...)

  • Аргументы: перегруженные версии для 0..10 пар ключ-значение; для большего числа пар используется Map.ofEntries(Map.Entry...).
  • Возвращаемое значение: неизменяемая Map. Ключи и значения не могут быть null.
  • При дублировании ключей выбрасывается IllegalArgumentException.

Map.ofEntries(Entry<K,V>... entries)

  • Аргументы: varargs записей, создаваемых с помощью Map.entry(k, v).
  • Возвращаемое значение: неизменяемая Map для произвольного числа пар.

Stream.of(T... values) / Stream.ofNullable(T)

  • Аргументы: varargs значений или одиночное значение для ofNullable.
  • Возвращаемое значение: java.util.stream.Stream. Stream.ofNullable возвращает пустой поток при null, иначе поток из одного элемента.

Optional.of(T value) / Optional.ofNullable(T value)

  • Аргументы: одиночное значение. Optional.of не принимает null - выбрасывает NullPointerException; Optional.ofNullable принимает null и возвращает Optional.empty().
  • Возвращаемое значение: java.util.Optional, контейнер, указывающий на присутствие или отсутствие значения.

EnumSet.of(E first, E... rest)

  • Аргументы: перечисление и дополнительные значения.
  • Возвращаемое значение: высокопроизводительный набор для enum, изменяемый по умолчанию (в отличие от прочих of-фабрик стандартных коллекций).

В сумме методы of служат для быстрого и наглядного создания коллекций и контейнеров. При выборе стоит учитывать требования к изменяемости, ограничению на null и на количество элементов (для Map.of).

Короткие примеры использования

Ниже приведены простые примеры с кодом и ожидаемым результатом.

List.of

import java.util.List;
public class Example1 {
  public static void main(String[] args) {
    List<String> list = List.of("a", "b", "c");
    System.out.println(list);
  }
}
[a, b, c]

Set.of (дубликаты приводят к ошибке)

import java.util.Set;
public class Example2 {
  public static void main(String[] args) {
    Set<Integer> set = Set.of(1, 2, 3);
    System.out.println(set);
  }
}
[1, 2, 3]

Map.of и Map.ofEntries

import java.util.Map;
import static java.util.Map.entry;
public class Example3 {
  public static void main(String[] args) {
    Map<String,String> m1 = Map.of("k1", "v1", "k2", "v2");
    Map<String,String> m2 = Map.ofEntries(entry("kA","vA"), entry("kB","vB"));
    System.out.println(m1);
    System.out.println(m2);
  }
}
{k1=v1, k2=v2}
{kA=vA, kB=vB}

Optional.ofNullable и Stream.ofNullable

import java.util.Optional;
import java.util.stream.Stream;
public class Example4 {
  public static void main(String[] args) {
    Optional<String> present = Optional.ofNullable("x");
    Optional<String> empty = Optional.ofNullable(null);
    System.out.println(present.isPresent());
    System.out.println(empty.isPresent());
    Stream.ofNullable(null).forEach(System.out::println);
  }
}
true
false

Похожие Java-методы и библиотеки

  • Arrays.asList - возвращает фиксированный, но изменяемый размером список, допускает null; удобен для адаптации массивов, но не обеспечивает полной неизменяемости.
  • Collections.singletonList / singletonMap / singleton - для создания коллекции ровно из одного элемента; чаще используется при экономии памяти и простоте.
  • List.copyOf / Set.copyOf / Map.copyOf - создают неизменяемую копию переданной коллекции; полезны при переносе данных от изменяемой структуры к неизменяемой.
  • Guava ImmutableList / ImmutableMap - сторонняя реализация неизменяемых коллекций с дополнительным функционалом и возможностью построения через билдеры.

Выбор между ними определяется требованиями к: мутабельности, поддержке null, производительности при малом числе элементов и совместимости с библиотеками.

Альтернативы в других языках

Kotlin

val list = listOf("a", "b")
val map = mapOf("k" to "v")
println(list)
println(map)
[a, b]
{k=v}

JavaScript

const arr = Array.of(1,2,3);
console.log(arr);
const map = new Map([["k","v"]]);
console.log(map);
[ 1, 2, 3 ]
Map { 'k' => 'v' }

Python

lst = ["a","b"]
st = set([1,2])
d = {"k":"v"}
print(lst)
print(st)
print(d)
['a', 'b']
{1, 2}
{'k': 'v'}

C#

var arr = new[] {1,2,3};
var list = new List<int>(arr);
Console.WriteLine(string.Join(", ", list));
1, 2, 3

Go

s := []int{1,2,3}
fmt.Println(s)
[1 2 3]

Отличия от Java: в Kotlin и Python фабрики возвращают структуры, которые могут быть неизменяемыми по контракту (Kotlin) или изменяемыми (Python). В JavaScript метод Array.of отличается от литерала массивов, но по назначению схож. Go и C# не имеют стандартного метода of, но используют литералы или конструкторы. Важно учитывать обработку null, поддержку дубликатов и семантику неизменяемости в конкретном языке.

Типичные ошибки и исключения

  • NullPointerException при попытке передать null в List.of или Optional.of. Пример:
import java.util.List;
public class Err1 {
  public static void main(String[] args) {
    List<String> list = List.of("a", null);
  }
}
Exception in thread "main" java.lang.NullPointerException
    at java.base/java.util.Objects.requireNonNull(Objects.java:...) ...
  • IllegalArgumentException при создании Set.of с дубликатами или Map.of с повторяющимися ключами:
import java.util.Set;
public class Err2 {
  public static void main(String[] args) {
    Set<Integer> set = Set.of(1, 1);
  }
}
Exception in thread "main" java.lang.IllegalArgumentException: duplicate element: 1
    at java.base/java.util.ImmutableCollections... 
  • UnsupportedOperationException при попытке модификации коллекции, возвращаемой List.of:
import java.util.List;
public class Err3 {
  public static void main(String[] args) {
    List<String> list = List.of("x");
    list.add("y");
  }
}
Exception in thread "main" java.lang.UnsupportedOperationException
    at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:...)
  • Использование Map.of с более чем 10 пар - перегрузки не подходят; потребуется Map.ofEntries.

Изменения в последних версиях Java

Основные нововведения были введены в Java 9: добавлены статические фабрики List.of, Set.of, Map.of и Map.ofEntries, а также Map.entry для удобного построения записей. Stream.of и Optional.of/ ofNullable появились раньше, в Java 8.

Позже были добавлены методы copyOf (List.copyOf, Set.copyOf, Map.copyOf) для создания неизменяемых копий существующих коллекций. В обновлениях точечного характера улучшалась производительность и кодогенерация неизменяемых реализаций, но семантика осталась стабильной.

Расширенные и редкие сценарии использования

Map.ofEntries для динамической сборки из пар

Пример java
import java.util.Map;
import static java.util.Map.entry;
public class Adv1 {
  public static void main(String[] args) {
    Map<String,Integer> map = Map.ofEntries(
      entry("a", 1), entry("b", 2), entry("c", 3)
    );
    System.out.println(map);
  }
}
{a=1, b=2, c=3}

Объединение потоков с помощью Stream.of и flatMap

Пример java
import java.util.stream.Stream;
public class Adv2 {
  public static void main(String[] args) {
    String[] a = {"x","y"};
    String[] b = {"1","2"};
    Stream.of(a, b)
          .flatMap(Stream::of)
          .forEach(System.out::print);
  }
}
xy12

Optional.ofNullable с ленивым значением через orElseGet

Пример java
import java.util.Optional;
public class Adv3 {
  public static void main(String[] args) {
    String v = null;
    String r = Optional.ofNullable(v).orElseGet(() -> expensive());
    System.out.println(r);
  }
  static String expensive() { return "computed"; }
}
computed

Создание неизменяемой копии от изменяемой коллекции

Пример java
import java.util.ArrayList;
import java.util.List;
public class Adv4 {
  public static void main(String[] args) {
    List<String> mutable = new ArrayList<>();
    mutable.add("a");
    List<String> immutable = List.copyOf(mutable); // Java 10+
    System.out.println(immutable);
  }
}
[a]

EnumSet.of для эффективных множеств перечислений

Пример java
enum Color { RED, GREEN, BLUE }
import java.util.EnumSet;
public class Adv5 {
  public static void main(String[] args) {
    EnumSet<Color> set = EnumSet.of(Color.RED, Color.BLUE);
    System.out.println(set);
  }
}
[RED, BLUE]

Дополнительно можно комбинировать List.of с коллекторами: например, Stream.concat(Stream.of(list1), Stream.of(list2)).collect(Collectors.toUnmodifiableList()) для получения объединенной неизменяемой коллекции.

джава of function comments

En
Of Obtains an instance of LocalDate from year, month and day