Очень вкусный фрукт Guava

Preview:

Citation preview

Очень вкусный фруктGuava

Вместо эпиграфаНе изобретайте колесо. Если вам нужно сделать нечто, что кажется

вполне обычным, в библиотеках уже может быть класс, который делает это. Вообще говоря, программный код в библиотеке наверняка окажется лучше кода, который вы напишете сами, а со временем он может стать еще лучше. Мы не ставим под сомнение ваши способности как программиста, однако библиотечному коду уделяется гораздо больше внимания, чем может позволить себе средний разработчик при реализации тех же функций.

Джошуа Блох. Эффективное программирование на Java.

Статья 47 “Изучите библиотеки и пользуйтесь ими”2

Философия библиотеки

● Тщательно разработана● Протестирована● Оптимизирована● Только повсеместно используемые

функции попадают в библиотеку

3

Зачем использовать GUAVA

● Сэкономить значительное количество написанного кода

● Избежать написания кода, который трудно отлаживать и в котором легко ошибиться

● Улучшить читабельность● Улучшить скорость работы программы.

4

Особенность удаления фич● В отличие от JDK удаляют

нежелательное поведение через некоторое время

● @Beta API● @Deprecated non @Beta компоненты

удаляются через 18 месяцев

5

Базовые утилиты● Работа с null. Optional● Preconditions● Objects, toString, equals,

hashCode● Компараторы с Ordering

6

Использование и избежание работы с null

● null - источник множества ошибок.

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

● Многие утилиты GUAVA где недопустимы null’ы бросают ошибку.

7

Optional<T>

null reference of T

Not null reference of T Present Optional<T>

Absent Optional<T>

8

Optional<T>методы создания

Optional.of(T)

Optional.absent()

Optional.fromNullable(T)

9

Optional<T>методы использования

boolean isPresent()

T get()

T or(T)

T orNull()

Set<T> asSet()10

Optional<T>. пример

private static Person nullPerson()

{

return null;

}

private static Person notNullPerson()

{

return new Person("Egor", "Chernyshev", 24);

}

11

Optional<T>. Пример

...

private static Person MARIA = new Person("Maria", "Petrova", 26);

...

Optional.of(nullPerson());// throws NullPointerExcepton

Optional.fromNullable(nullPerson()).or(MARIA); // Person{lastName=Petrova, firstName=Maria, age=26}

Optional.fromNullable(notNullPerson()).or(MARIA); // Person{lastName=Chernyshev, firstName=Egor, age=24}

Optional.fromNullable(nullPerson()).orNull(); // null

Optional.fromNullable(notNullPerson()).orNull();// Person{lastName=Chernyshev, firstName=Egor, age=24}

Optional.fromNullable(nullPerson()).asSet(); // []

Optional.fromNullable(notNullPerson()).asSet();// [Person{lastName=Chernyshev, firstName=Egor, age=24}]

Optional.absent().get();// throws IllegalStateException

...

12

Preconditions

13

Preconditions

...

import static com.google.common.base.Preconditions.checkArgument;

import static com.google.common.base.Preconditions.checkElementIndex;

import static com.google.common.base.Preconditions.checkNotNull;

import static com.google.common.base.Preconditions.checkPositionIndex;

import static com.google.common.base.Preconditions.checkPositionIndexes;

import static com.google.common.base.Preconditions.checkState;

...

14

Preconditions int positive = 1;

checkArgument(positive > 0, "Number %s must be a positive", positive); // IllegalArgumentException:

//Number 1 must be a negative

checkArgument(positive < 0, "Number %s must be a negative", positive); // IllegalArgumentException:

//Number 1 must be a negative

Object nullValue = null;

checkNotNull(nullValue, "Value mast be not null"); // NullPointerException: Value mast be not null

checkState(positive < 0); // IllegalStateException

checkElementIndex(5, 6);

checkElementIndex(6, 6); // IndexOutOfBoundsException: index (6) must be less than size (6)

checkPositionIndex(6, 6);

checkPositionIndexes(3, 4, 4);

15

Object Utilities.

equals, hashCode, toStringcompareTo

16

public class Person implements Comparable<Person>

{

private String firstName;

private String lastName;

private int age;

public Person(String firstName, String lastName, int age)

{

this.firstName = firstName;

this.lastName = lastName;

this.age = age;

}

getters and setters

...

}17

equals()...

@Override

public boolean equals(Object obj)

{

if (this == obj) return true;

if (obj == null) return false;

if (getClass() != obj.getClass()) return false;

Person other = (Person) obj;

return Objects.equals(lastName, other.lastName) &&

Objects.equals(firstName, other.firstName) &&

Objects.equals(age, other.age);

}

...18

hashCode()

...

@Override

public int hashCode()

{

return Objects.hash(lastName, firstName, age);

}

...

19

toString()...

@Override

public String toString()

{

return MoreObjects.toStringHelper(this)

.add("lastName", lastName)

.add("firstName", firstName)

.add("age", age)

.toString();

}

...

Person{lastName=Chernyshev, firstName=Egor, age=24}20

compareTo()...

@Override

public int compareTo(Person o)

{

return ComparisonChain.start()

.compare(lastName, o.lastName)

.compare(firstName, o.firstName)

.compare(age, o.age)

.result();

}

...

21

Ordering

утилита для работы с упорядоченными объектами

22

Ordering

● Ordering<T> - наследник Comparator<T>

● В Ordering реализованы методы использующие порядок: min, max, sort и т.д.

23

Ordering<T>. Создание ● Ordering.natural() - естественный порядок,

основанный на функции compare(T,T)● Ordering.usingToString() - лексикографический

порядок, строковых представлений (toString)● Ordering.from(Comparator)● Наследник Ordering

24

Ordering<T>. ИспользованиеgreatestOf(Iterable iterable, int k) See also: leastOf

isOrdered(Iterable)See also: isStricklyOrdered

sortedCopy(Iterable)See also: immutableSortedCopy

min(E, E)See also: max(E, E)

min(E, E, E, E...)See also: max(E, E, E, E...)

min(Iterable)See also: max(Iterable), min(Iterator), max(Iterator)

25

FirstName Ordering

private static Ordering<Person> FIRST_NAME_ORDERING =

Ordering.natural().nullsFirst().onResultOf(new Function<Person, String>()

{

@Override

public String apply(Person input)

{

return input.getFirstName();

}

});

26

Age Ordering

private static Ordering<Person> AGE_ORDERING =

Ordering.natural().onResultOf(new Function<Person, Integer>()

{

@Override

public Integer apply(Person input)

{

return input.getAge();

}

});

27

Список Person

private static List<Person> createPersonList()

{

return Lists.newArrayList(

new Person("Egor", "Chernyshev", 24),

new Person("Anton", "Borisov", 36),

new Person("Elena", "Petrova", 18),

new Person("Maxim", "Lobanov", 65),

new Person(null, "Alexandrova", 24));

}

28

List<Person> persons = createPersonList();

out.println("isOrdered =" + FIRST_NAME_ORDERING.isOrdered(persons)); // isOrdered =false

Collections.sort(persons, FIRST_NAME_ORDERING);

out.println(persons);// [Person{lastName=Alexandrova, firstName=null, age=24},

// Person{lastName=Borisov, firstName=Anton, age=36},

// Person{lastName=Chernyshev, firstName=Egor, age=24},

// Person{lastName=Petrova, firstName=Elena, age=18},

// Person{lastName=Lobanov, firstName=Maxim, age=65}]

out.println("isOrdered =" + FIRST_NAME_ORDERING.isOrdered(persons)); // isOrdered =true

out.println(AGE_ORDERING.max(persons)); // Person{lastName=Lobanov, firstName=Maxim, age=65}

out.println(AGE_ORDERING.min(persons)); // Person{lastName=Petrova, firstName=Elena, age=18}

Ordering<T>. Примеры

29

Ordering<T>. Примеры

Ordering<Person> compound = Ordering.compound(Lists.newArrayList(AGE_ORDERING,

FIRST_NAME_ORDERING));

List<Person> compoundSortedPersons = compound.sortedCopy(createPersonList());

out.println(compoundSortedPersons); // [Person{lastName=Petrova, firstName=Elena, age=18},

// Person{lastName=Alexandrova, firstName=null, age=24},

// Person{lastName=Chernyshev, firstName=Egor, age=24},

// Person{lastName=Borisov, firstName=Anton, age=36},

// Person{lastName=Lobanov, firstName=Maxim, age=65}]

30

GUAVA Collections

● ImmutableCollections● Новые коллекции в Guava● Утилитарные классы Sets, Lists, Maps…● Утилиты для расширения java коллекций31

Immutable Collections

32

Чем хороши Immutable objects?

● Безопасное использование в untrusted библиотеках.

● Потоко безопасны.● Хороши для хранения констант, так как

есть гарантия неизменяемости.

33

Interface JDK или Guava Immutable version

Collection JDK ImmutableCollection

List JDK ImmutableList

Set JDK ImmutableSet

SortedSet / NavigableSet

JDK ImmutableSortedSet

Map JDK ImmutableMap

SortedMap JDK ImmutableSortedMap

Multiset Guava ImmutableMultiset34

Interface JDK или Guava Immutable version

SortedMultiset Guava ImmutableSortedMultiset

Multimap Guava ImmutableMultimap

ListMultimap Guava ImmutableListMultimap

SetMultimap Guava ImmutableSetMultimap

BiMap Guava ImmutableSetMultimap

ClassToInstanceMap

Guava ImmutableClassToInstanceMap

Table Guava ImmutableTable35

ImmutableCollection. Создание

● ImmutableXXX.of● ImmutableXXX.copyOf● ImmutableXXX.builder()

36

ImmutableXXX.copyOf

ImmutableList<Person> GROUP = ImmutableList.of(

new Person("Egor", "Chernyshev", 24),

new Person("Anna", "Tarasova", 30));

ImmutableSet<String> ALPHABET = ImmutableSet.of("a", "b", "c");

ImmutableMap<String, Integer> CHAR_NUMBERS = ImmutableMap.of("a", 1, "b", 2);

ImmutableXXX.of

ImmutableList<Person> COPY_OF_GROUP = ImmutableList.copyOf(GROUP);

37

ImmutableXXX.builder()

ImmutableList<Person> GROUP_B = ImmutableList

.<Person>builder()

.addAll(GROUP)

.add(new Person("Anton", "Belov", 41))

.build();

38

copyOf умнее, чем вы думаете

● copyOf пытается избежать полного копирования объектов.

● В общем случае ImmutableXXX.copyOf(ImmutableXXX) пытается выполнится за O(1), за исключением некоторых случаев

39

исключения● ImmutableSet.copyOf(ImmutableList)

● ImmutableList<String> hugeList;

ImmutableList.copyOf(hugeList.subList(0, 10))

● ImmutableSet.copyOf (myImmutableSortedSet)

40

Multiset

41

Multiset

Мультимножество: {a, a, b, c, f, d}

Эквивалентность:{a, a, b} = {a, b, a}

42

Multiset. Пример

Multiset<Character> toCharsMultiset(String text)

{

return HashMultiset.create(Chars.asList(text.toCharArray()));

}

Подсчет количества каждого символа в тексте:

43

Multiset. РеализацииMap Соответствующий Multiset Допускает null?

HashMap HashMultiset Да

TreeMap TreeMultiset Да (если компаратор поддерживает)

LinkedHashMap LinkedHashMultiset Да

ConcurrentHashMap ConcurrentHashMultiset Нет

ImmutableMap ImmutableMultiset Нет

44

Multimap

45

Multimap

a->1, a->2, a->4, b->3, c->5или

a->[1, 2, 4], b->3, c->5

Map<K, List<V>> Map<K, Set<V>>

Multimap<K, V>

46

Multimap<K,V>. Представления

Multimap<K,V>.asMap() Map<K, Collection<V>>

Multimap<K,V>.entries() Collection<Entry<K,V>>

Multimap<K,V>.keySet() Set<K>

Multimap<K,V>.keys() Multiset<K>

Multimap<K,V>.values() Collection<V>

47

Multimap<K,V>. РеализацииРеализация Ключи ведут себя как... Значения ведут себя как...

ArrayListMultimap HashMap ArrayList

HashMultiMap HasMap HashSet

LinkedListMultimap LinkedHashMap LinkedList

LinkedHashMultiMap LinkedHashMap LinkedHashSet

TreeMultimap TreeMap TreeSet

ImmutableListMultimap ImmutableMap ImmutableList

ImmutableSetMultimap ImmutableMap ImmutableSet48

Multimap. Пример

private static Function<Person, String> FIRST_NAME_EXTRACTOR = new

Function<Person, String>()

{

@Override

public String apply(Person input)

{

return input.getFirstName();

}

};

49

Multimap. Пример List<Person> PERSONS = Lists.newArrayList(

new Person("Egor", "Chernyshev", 24),

new Person("Anton", "Borisov", 36),

new Person("Elena", "Petrova", 18),

new Person("Elena", "Birkova", 11),

new Person("Maxim", "Lobanov", 65));

Multimap<String, Person> index = Multimaps.index(PERSONS, FIRST_NAME_EXTRACTOR);

50

BiMap

51

BiMap<K,V>

BiMap<V, K> - это Map<K, V>, в которой

● Добавлен метод BiMap<V, K> inverse().

● Есть проверка на уникальность значений.

● values() возвращает Set<V>.52

BiMap<K,V>. РеализацииKey-Value Map Value-Key Map Реализация

HashMap HashMap HashBiMap

ImmutableMap ImmutableMap ImmutableBiMap

EnumMap EnumMap EnumBiMap

EnumMap HashMap EnumHashBiMap

53

Table

54

Table<R, C, V>

● Table - это способ хранения индекса объекта по двум ключам R и C.

● Table<R,C,V> заменяет неуклюжую реализацию структуры

Map<R, Map<C, V>>55

Table<R, C, V>. Представления

Table<R,C,V>.rowMap() Map<R, Map<C,V>>

Table<R,C,V>.rowKeySet() Set<R>

Table<R,C,V>.row(r) Map<C,V>

columnMap(), columnKeySet(), column(c)

Аналогично, row. Column access по производительности работает медленнее, чем row access из за структуры данных.

Table<R,C,V>.cellSet() Set<Table.Cell<R,C,V>>

56

Table<R, C, V>. РеализацииРеализация На основе структуры

HashBasedTable HashMap<R, HashMap<C, V>>

TreeBasedTable TreeMap<R, TreeMap<C, V>>

ImmutableTable ImmutableMap<R, ImmutableMap<C, V>>

ArrayTable Двумерный массив. Хорошо подходит для задач, с сильно заполненными таблицами.

57

ClassToInstanceMap

58

ClassToInstanceMap<B>

● Реализация Map<Class<? extends B>, B>● Поддерживает примитивы

Реализации:● ImmutableClassToInstanceMap● MutableClassToInstanceMap

59

public interface MegaService {}

public class SuperMegaService implements MegaService{}

public class SuperMegaBupperService implements MegaService{}

private static final ClassToInstanceMap<MegaService> REGISTRY = MutableClassToInstanceMap.create();

REGISTRY.putInstance(SuperMegaService.class, new SuperMegaService());// OK

REGISTRY.putInstance(SuperMegaBupperService.class, new SuperMegaBupperService());// OK

REGISTRY.putInstance(MegaService.class, new SuperMegaBupperService());// OK

REGISTRY.putInstance(SuperMegaService.class, new SuperMegaBupperService()); // Ошибка компиляции

REGISTRY.putInstance(String.class, "qqqq"); // Ошибка компиляции

REGISTRY.put(String.class, "qqqq"); // Ошибка компиляции

REGISTRY.getInstance(MegaService.class);// OK

REGISTRY.getInstance(String.class);// Ошибка компиляции

60

RangeSet

61

RangeSet<C extends Comparable>

RangeSet<Integer> rangeSet = TreeRangeSet.create();

rangeSet.add(Range.closed(1, 10)); // {[1, 10]}

rangeSet.add(Range.closedOpen(11, 15)); // disconnected range: {[1, 10], [11, 15)}

rangeSet.add(Range.closedOpen(15, 20)); // connected range; {[1, 10], [11, 20)}

rangeSet.add(Range.openClosed(0, 0)); // empty range; {[1, 10], [11, 20)}

rangeSet.remove(Range.open(5, 10)); // splits [1, 10]; {[1, 5], [10, 10], [11, 20)}

● JDK 1.6 +● Не поддерживается в GWT

62

RangeSet<C>. Представления

RangeSet<C>.subRangeSet(Range<C>) RangeSet<C>

RangeSet<C>.asRanges() Set<Range<C>>

RangeSet<C>.asSet(DiscreteDomain<C>)только ImmutableRangeSet

ImmutableSortedSet<C>

63

RangeSet<C>. ЗапросыМетод Возвращаемое значение

RangeSet<C>.contains(C) boolean

RangeSet<C>.rangeContaining(C) Range<C>

RangeSet<C>.encloses(Range<C>) boolean

RangeSet<C>.span() Range<C>

64

RangeMap

65

Collections UtilsКоллекция JDK или Guava Класс с утилитами

Collection JDK Collections2

List JDK Lists

Set JDK Sets

SortedSet JDK Sets

Map JDK Maps

SortedMap JDK Maps

Queue JDK Queues66

Collections UtilsКоллекция JDK или Guava Класс с утилитами

Multiset Guava Multisets

Multimap Guava Multimaps

BiMap Guava Maps

Table Guava Tables

67

Static constructors List<TypeThatsTooLongForItsOwnGood> list = new ArrayList<TypeThatsTooLongForItsOwnGood>();

------------------------------------------------------------------------------------------

List<TypeThatsTooLongForItsOwnGood> list1 = Lists.newArrayList();

Map<KeyType, LongishValueType> map = Maps.newLinkedHashMap();

------------------------------------------------------------------------------------------

List<TypeThatsTooLongForItsOwnGood> list2 = new ArrayList<>();

------------------------------------------------------------------------------------------

Set<Type> copySet = Sets.newHashSet(elements);

List<String> theseElements = Lists.newArrayList("alpha", "beta", "gamma");

------------------------------------------------------------------------------------------

List<Type> exactly100 = Lists.newArrayListWithCapacity(100);

List<Type> approx100 = Lists.newArrayListWithExpectedSize(100);

Set<Type> approx100Set = Sets.newHashSetWithExpectedSize(100);

------------------------------------------------------------------------------------------

Multiset<String> multiset = HashMultiset.create();68

Iterables

● Guava предпочитает Iterable вместо Collection

● Многие Iterable являются Lazy● Утилита FluentItrable, оборачивает

Iterable и предоставляет набор методов для работы в функцинальном стиле.

69

Lists

Метод Описание

partiton(List, int) List<List> - разбиение списка на подсписки определенной длины.

reverse(List) Развернутое представление списка

70

Sets

Метод Описание

union(Set, Set) Объединение множеств

intersection(Set, Set) Пересечение

difference(Set, Set) Разность

symmetricDifference(Set, Set) симметричная разность

powerSet(Set) Множество всех подмножеств

71

Maps

72

Maps.uniqueIndex()Maps.uniqueIndex(Lists.newArrayList("dddd", "ddddd", "qwcccccde"), new Function<String, Integer>()

{

@Override

public Integer apply(String input)

{

return input.length();

}

});

//{4=dddd, 5=ddddd, 9=qwcccccde}

● Выбросится ошибка, если Function вернет неуникальное значение73

MapDifference d = Maps.difference()

entriesInCommon()entriesOnlyOnLeft() entriesOnlyOnRight()

entriesDiffering()74

Multimaps

Метод Описание

index(Iterable, Function) Построение индекса коллекции по ключевой функции

invertFrom(Multimap, Multimap) Разворот Map’ы (<K,V> -> <V,K>)

forMap(Map) Преобразвание Map<K,V> в Multimap<K,V>

75

Tables

Метод Описание

transpose(Table<R,C,V>) Транспонирование таблицы Table<R,C,V> -> Table<C,R,V>

76

Extention utilities

● Forwarding Decorators● PeekingIterator● AbstractIterator

77

Forwarding Decorators. Примерclass AddLoggingList<E> extends ForwardingList<E> {

final List<E> delegate; // backing list

@Override protected List<E> delegate() {

return delegate;

}

@Override public void add(int index, E elem) {

log(index, elem);

super.add(index, elem);

}

@Override public boolean add(E elem) {

return standardAdd(elem); // implements in terms of add(int, E)

}

@Override public boolean addAll(Collection<? extends E> c) {

return standardAddAll(c); // implements in terms of add

}

}

78

Forwarding DecoratorsInterface Forwarding decorator

Collection ForwardingCollection

List ForwardingList

Set ForwardingSet

SortedSet ForwardingSortedSet

Map ForwardingMap

SortedMap ForwardingSortedMap

ConcurrentMap ForwardingConcurrentMap

Map.Entry ForwardingMapEntry79

Interface Forwarding decorator

Queue ForwardingQueue

Iterator ForwardingIterator

ListIterator ForwardingListIterator

Multiset ForwardingSortedSet

Multimap ForwardingMultiset

ListMultiMap ForwardingListMultiMap

SetMultimap ForwardingSetMultimap

Forwarding Decorators

80

PeekingIterator

List<String> result = Lists.newArrayList();

PeekingIterator<String> iter = Iterators.peekingIterator(source.iterator());

while (iter.hasNext()) {

String current = iter.next();

while (iter.hasNext() && iter.peek().equals(current)) {

// skip this duplicate element

iter.next();

}

result.add(current);

}

81

AbstractIteratorpublic static Iterator<String> skipNulls(final Iterator<String> in) {

return new AbstractIterator<String>() {

protected String computeNext() {

while (in.hasNext()) {

String s = in.next();

if (s != null) {

return s;

}

}

return endOfData();

}

};

}82

CachesКэширование информации в памяти.

Применимость, создание кэшей, использование примеры.

83

Cache. Применимость

● Память -> Скорость

● Элемент используется больше 1 раза

● Все кэшируемые значения помещаются в оперативной памяти

84

Cache. Создание

Cache<String, Person> cache = CacheBuilder

.newBuilder()

.expireAfterAccess(5, TimeUnit.MINUTES)

.maximumSize(10000)

.build();

85

Cache. Добавление значенияCacheLoader

/**

* Медленная операция получения человека по Web сервису

* из внешней системы

*/

private Person loadPersonByWebService(String key)

{

return new Person("Anton", "Borisow", 88);

}

86

Cache. Добавление значенияCacheLoader

Cache<String, Person> cache = CacheBuilder

.newBuilder()

.expireAfterAccess(5, TimeUnit.MINUTES)

.maximumSize(10000)

.build(new CacheLoader<String, Person>()

{

@Override

public Person load(String key) throws Exception

{

return loadPersonByWebService(key);

}

});

87

Cache. Добавление значенияfrom Callable

try{

cache.get(key, new Callable<Person>(){

@Override

public Person call() throws Exception

{

return loadPersonByWebService(key);

}

});

}

catch (ExecutionException e)

{

throw new RuntimeException(e.getMessage(), e);

}88

Cache. Добавление значенияdirectly insert

cache.put(key, loadPersonByWebService(key));

89

Cache. Eviction

● Size-base eviction● Timed eviction● Reference-based eviction● Explicit eviction● Removal Listener

90

Cache. Size-based eviction

● CacheBulder.maximumSize(long)

● CacheBuilder.maximumWeight(long)

● CacheBuilder.weighter(Weighter<K,V>)

91

Cache. Timed eviction● CacheBuilder.expireAfterWrite(long, TimeUnit)

● CacheBuilder.expireAfterAccess(long, TimeUnit)

92

Cache. Reference-based eviction

● CacheBulder.weakKeys()

● CacheBuilder.weakValues()

● CacheBuilder.softValues()

93

Cache. Explicit removals

● Cache.invalidate(key)

● Cache.invalidateAll(keys)

● Cache.invalidateAll()

94

Cache. Когда происходит eviction

● В момент записи нового значения

● Иногда (если записей в кэш мало) при получении значения по ключу

● Кэш не обслуживается отдельным потоком!95

Cache. Прочие возможности

● Statistic:Включение: CacheBuilder.recordStats();Получение: CacheStats stats = Cache.stats();Использование:

● stats.hitRate() - количество попаданий● stats.averageLoadPenalty() - среднее время на загрузку

новых значений● stats.evictionCount() - количество eviction’ов

● asMap96

Мощные, простые инструменты для написания корректного

многопоточного кода

ListenableFutures, Service, Striped

97

ListenableFuture

● Расширяет Future - позволяет регистрировать Callback на момент выполнения операции.

● Callback будет вызван один раз.● Callback обрабатывает ошибки с

помщью onFaiture() метода.98

DocumentLoaderService

private ListeningExecutorService executorService = MoreExecutors

.listeningDecorator(Executors.newFixedThreadPool(5));

public void loadDocument(final String docUrl, FutureCallback<String> callback){

ListenableFuture<String> future = executorService.submit(new Callable<String>(){

@Override

public String call() throws Exception{

return IOUtils.toString(docUrl, StandardCharsets.UTF_8.name());

}

});

Futures.addCallback(future, callback);

}

… 99

DocumentLoaderService service = DocumentLoaderService.instance();

for (String url : TESTED_URLS)

{

service.loadDocument(url, new FutureCallback<String>(){

@Override

public void onSuccess(String result){

handleDocument(result);

}

@Override

public void onFailure(Throwable t){

handleError(t);

}

});

}

DocumentLoaderService. Использование

100

Service

101

Service

● Интерфейс Service - это объект с рабочим состоянием и методами остановки и запуска.

● Service имеет ряд предопределенных состояний.

● Существуют базовые абстрактные реализации, которые необходимо переопределять для написания собственных служб и сервисов.102

Использование Service

NEW STARTING RUNNING STOPPING TERMINATED

Метод Описание

startAsync() Запуск

stopAsync() Остановка

state() Статус103

Serivce. Базовые реализации

● AbstractIdleService● AbstractExecutionThreadService● AbstractScheduledService● AbstractService

104

ServiceMangerМетод Описание

startAsync() Стартует все службы

stopAsync() Останавливает все службы

addListener Добавление листенеров на смены статусов

awaitHealthy() дождаться пока все службы не станут RUNNING

awaitStopped() дождаться пока все службы не будут остановлены

isHealthy() true, если все службы RUNNING

servicesByState() ultimap сервисов сгрупированных по состояниям

startupTimes() Map сервисов с временами старта. Отсортированная105

Striped

106

Striped. Пример private Lock lock = new ReentrantLock();

public void runAction(String key)

{

lock.lock();

try

{

threadSafeActionWithResource(getResource(key));

}

finally

{

lock.unlock();

}

}107

Striped. Пример private Striped<Lock> striped = Striped.lazyWeakLock(2);

public void runAction(String key)

{

Lock lock = striped.get(key);

lock.lock();

try

{

threadSafeActionWithResource(getResource(key));

}

finally

{

lock.unlock();

}

}

108

Прочие утилитыStrings, Joiner, Splitter, CharMatcher

и пр.

109

Strings

Метод Описание

isNullOrEmpty(str) true,если str == null или str.length() == 0

nullToEmpty(str) Преобразуется null в “”

emptyToNull(str) Преобразует “” в null

repeat(str, int) Повторяет str строку int раз

110

Joiner

Joiner joiner = Joiner.on(", ").useForNull("null");

List<String> parts = Lists.newArrayList("alpha", "beta", "gamma");

parts.add(null);

String joined = joiner.join(parts);

// alpha, beta, gamma, null

111

Splitter

Iterable<String> splited = Splitter

.on(",")

.omitEmptyStrings()

.split("aa,,ddd,,bb,b,bbbb,ffd");

//[aa, ddd, bb, b, bbbb, ffd]

112

CharMatcher

113

PrimitivesПримитивный тип Утилиты

byte Bytes, SignedBytes, UnsignedBytes

short Shorts

int Ints, UnsignedInteger, UnsignedInts

long Longs, UnsignedLong, UnsignedLongs

float Floats

double Doubles

char Chars

boolean Booleans114

Ranges

115

MathIntMath, LongMath, BigIntegerMath

116

Hashing

● md5● sha256● sha1● sha512● murmur2_128● murmur3_32

117

Вопросы?

Егор Чернышев

email: egrik1990@gmail.com

Skype: egrik1990