Re[2]: Через год-два .NET Core потеснит Java на рынке enterprise решений
От: mrTwister Россия  
Дата: 22.04.20 08:25
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>При этом в самом .NET пока что нет каких-то "killer feature".


Асинхронщина разве что
лэт ми спик фром май харт
Re[3]: Через год-два .NET Core потеснит Java на рынке enterprise решений
От: Clerk  
Дата: 22.04.20 08:47
Оценка: +2 :)
Здравствуйте, mrTwister, Вы писали:

C>>При этом в самом .NET пока что нет каких-то "killer feature".


T>Асинхронщина разве что


А как же LINQ?
В JAVA есть аналог linq2db?
Re[21]: Через год-два .NET Core потеснит Java на рынке enter
От: Mamut Швеция http://dmitriid.com
Дата: 22.04.20 08:57
Оценка: +14
vsb>по-мне одинаково понятный в обоих случаях. В .NET сделали ограниченную реализацию, в Java более общую и удобную, вот и вся разница.

«Общие реализации в Java»

Используй Collection (а не Iterable)

Не используй массивы

Ничего не надо реализовывать... вот простейшая реализация коллекции, в которой

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

В Java 11 есть инициализаторы коллекций ... захардкоженные List.of, Map.of, Set.of....


Прям отличные общие и удобные решения, ага.

«Ограниченная реализация .Net»: реализуешь IEnumerable. Все работает из коробки. Если не хватает каких-то методов, работающих на IEnumerable, пишешь extension method, который автоматом работает на всех IEnumerable. Ужасно ограниченно и неудобно, да.


dmitriid.comGitHubLinkedIn
Отредактировано 22.04.2020 9:02 Mamut [ищите в других сетях] . Предыдущая версия .
Re[20]: Через год-два .NET Core потеснит Java на рынке enter
От: vsb Казахстан  
Дата: 22.04.20 12:46
Оценка:
Здравствуйте, takTak, Вы писали:

T>разница от дотнет в том, что в случае явы нужно тащить технические концепции в код, который просто должен вывести параллельно список букв, в дотнете необходимости в этом нет


Какие концепции? ForkJoinPool? Ну оно же не на магии работает. Естественно надо тащить.

T>мне непонятно:

T>последний .join() блокирует UIThread\MainThread или нет ?

Блокирует. Это кусок main-а, если его не написать, то main завершается прежде, чем отработает задача и ничего не будет распечатано. Если не надо блокировать — не блокируй.

T>допустим, при выведении "b" в .forEach происходит исключение, как ты его будет отлавливать ? повлияет ли это исключение на вывод других букв?


После первого исключения всё остановится и join() выбросит это исключение.

T>допустим, ты хочешь прервать выведение "c" в .forEach, как ты будешь это делать ?


Я думаю, это некорректная постановка задачи. Но можно тупо бросить исключение, да, оно остановится всё. А вообще надо писать так, чтобы не было такой задачи, исключения для исключительных ситуаций, а не для контроля потока выполнения. Можно написать forkJoinPool.shutdownNow(); тогда при попытке выполнить следующую задачу оно кинет CancellationException, тоже не слишком хорошо, но, наверное, это ближе всего к желаемому.

T>если ты хочешь, чтобы вначале вывелось буква "б", а после неё вывелась бы буква "в" , будет ли еxecutor или что там в яве есть, располагать их в одном и том же потоке, чтобы минимизировать переключение между потоками или тебе нужно руками это прописывать? стандартный дотнетовский taskscheduler такое делает за меня автоматически


forEach это параллельная конструкция. Он разбрасывает все элементы по executor-ам в абсолютно случайном порядке.

T>по какому алгоритму происходит распределение задач в пуле потоков? work stealing в стандартной яве используется?


Да.
Отредактировано 22.04.2020 12:50 vsb . Предыдущая версия .
Re[11]: Через год-два .NET Core потеснит Java на рынке enterp
От: bzig  
Дата: 22.04.20 14:29
Оценка:
AK>Жаль, что узнал это за пару дней перед уходом с текущей работы.

Не стрёмно в такое время работу менять? У нас прошли сокращения (небольшие пока), как раз новички в основном под нож пошли.
Re[15]: Через год-два .NET Core потеснит Java на рынке enterprise решений
От: Dziman США http://github.com/Dziman
Дата: 22.04.20 17:31
Оценка:
Здравствуйте, Artem Korneev, Вы писали:

AK>Здравствуйте, Dziman, Вы писали:


D>>А ты в какой компании? Звучит очень заманчиво, что этот ломбок-рак не используете


AK>VMware.

AK>Я за всю компанию сказать не могу, могу только сказать что в тех командах, в которых я был (NSX), ломбок не использовался. Но компания большая. Даже наш бизнес-юнит большой. Я не знаю, что используют команды в соседнем здании или даже на другом этаже.

AK>А чем вам так ломбок не понравился?


Основная претензия в том он ломает половину полезных фич у IDEA:
— не все рефакторинги отрабатывают корректно. Например, добавляется final field и он автоматом добавляется в all-args/required-args и теперь нужно вручную пойти и везде где этот конструктор используется зафигачить этот филд
— сломанная навигация: как найти использование no-arg или all-arg конструкторов
— если спринговские бины инжектяться при помощи сгенерированного конструктора, то нет легкой возможности легко увидеть какой конкретно бин заинжектился
— (не напрямую ломбок виноват, но всё же) Автогенерируемые equals/hashCode/toString могут иметь неявные последствия. Например, в лог захотят записать что-то типа log.error("Entity val: {}", entity) а т.к. в entity 5 lazy collection, то ломбок их вытащит и зафигачит в стринг, а на деле в логе хватило бы entity.name + entity.id
Это что сразу всплыло в памяти

(может это уже не актуально) Сам факт манипуляций с байткодом через недокументированную/не публичную функциональность jdk.
Re[12]: Через год-два .NET Core потеснит Java на рынке enterp
От: Dziman США http://github.com/Dziman
Дата: 22.04.20 17:37
Оценка:
Здравствуйте, bzig, Вы писали:


AK>>Жаль, что узнал это за пару дней перед уходом с текущей работы.


B>Не стрёмно в такое время работу менять? У нас прошли сокращения (небольшие пока), как раз новички в основном под нож пошли.

В некоторых случаях стрёмнее оставаться на текущем месте. Вот например, я в 'travel' компании и будущее оочень смутное.
Re[12]: Через год-два .NET Core потеснит Java на рынке enterp
От: Artem Korneev США https://www.linkedin.com/in/artemkorneev/
Дата: 23.04.20 00:09
Оценка: 1 (1)
Здравствуйте, bzig, Вы писали:

AK>>Жаль, что узнал это за пару дней перед уходом с текущей работы.

B>Не стрёмно в такое время работу менять?

Есть немного.
Я подписал оффер ещё в январе, но переход запланировал на апрель — хотел получить все причитающиеся бонусы и акции, жалко было бросать. В январе всей этой паники с вирусом ещё не было, не говоря уже о сокращениях. Новости о вирусе воспринимались как какой-то фоновый шум. Ну как максимум — предостережение не ездить в Китай в отпуск.

Ну а теперь уже не хочется давать по тормозам. Раз решил переходить, значит буду переходить.

B>У нас прошли сокращения (небольшие пока), как раз новички в основном под нож пошли.


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

Сейчас я наверное не стал бы рыпаться на собеседования. Но раз уж договорился обо всём заранее — буду рисковать.
С уважением, Artem Korneev.
Re[16]: Через год-два .NET Core потеснит Java на рынке enterprise решений
От: Cyberax Марс  
Дата: 23.04.20 01:07
Оценка:
Здравствуйте, Dziman, Вы писали:

D>- сломанная навигация: как найти использование no-arg или all-arg конструкторов

Переходим на "file structure", там все конструкторы будут развёрнуты. Находим нужный элемент и ищем использование.

D>- если спринговские бины инжектяться при помощи сгенерированного конструктора, то нет легкой возможности легко увидеть какой конкретно бин заинжектился

Не надо так использовать Spring. Это плохой, негодный код.

D>- (не напрямую ломбок виноват, но всё же) Автогенерируемые equals/hashCode/toString могут иметь неявные последствия. Например, в лог захотят записать что-то типа log.error("Entity val: {}", entity) а т.к. в entity 5 lazy collection, то ломбок их вытащит и зафигачит в стринг, а на деле в логе хватило бы entity.name + entity.id

D>Это что сразу всплыло в памяти
Не надо использовать lazy-коллекции.

D>(может это уже не актуально) Сам факт манипуляций с байткодом через недокументированную/не публичную функциональность jdk.

Вообще-то, Lombok работает через документированный интерфейс агентов инструментирования: https://docs.oracle.com/en/java/javase/11/docs/api/java.instrument/java/lang/instrument/package-summary.html
Sapienti sat!
Re[17]: Через год-два .NET Core потеснит Java на рынке enterprise решений
От: Dziman США http://github.com/Dziman
Дата: 23.04.20 04:34
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, Dziman, Вы писали:


D>>- сломанная навигация: как найти использование no-arg или all-arg конструкторов

C>Переходим на "file structure", там все конструкторы будут развёрнуты. Находим нужный элемент и ищем использование.
ОК, можно. Но сравни с Cmd+Click/Cmd+B(GoTo) из кода

D>>- если спринговские бины инжектяться при помощи сгенерированного конструктора, то нет легкой возможности легко увидеть какой конкретно бин заинжектился

C>Не надо так использовать Spring. Это плохой, негодный код.
А как надо? @Autowired?

D>>- (не напрямую ломбок виноват, но всё же) Автогенерируемые equals/hashCode/toString могут иметь неявные последствия. Например, в лог захотят записать что-то типа log.error("Entity val: {}", entity) а т.к. в entity 5 lazy collection, то ломбок их вытащит и зафигачит в стринг, а на деле в логе хватило бы entity.name + entity.id

D>>Это что сразу всплыло в памяти
C>Не надо использовать lazy-коллекции.
Сразу eager лепить чтоли ?

D>>(может это уже не актуально) Сам факт манипуляций с байткодом через недокументированную/не публичную функциональность jdk.

C>Вообще-то, Lombok работает через документированный интерфейс агентов инструментирования: https://docs.oracle.com/en/java/javase/11/docs/api/java.instrument/java/lang/instrument/package-summary.html
Может в более свежих JDK с этим стало получше и/или это нужно не для всех аннотаций.
Re[18]: Через год-два .NET Core потеснит Java на рынке enterprise решений
От: Cyberax Марс  
Дата: 23.04.20 05:53
Оценка:
Здравствуйте, Dziman, Вы писали:

D>>>- сломанная навигация: как найти использование no-arg или all-arg конструкторов

C>>Переходим на "file structure", там все конструкторы будут развёрнуты. Находим нужный элемент и ищем использование.
D>ОК, можно. Но сравни с Cmd+Click/Cmd+B(GoTo) из кода
Это если конструктор на экране перед глазами, а не затерялся в простыне getter/setter'ов.

Кстати, насколько я помню, рефакторинг "добавить поле" там тоже работал. Сейчас лень ставить IDEA.

C>>Не надо так использовать Spring. Это плохой, негодный код.

D>А как надо? @Autowired?
Надо использовать внешнюю конфигурацию.

D>>>Это что сразу всплыло в памяти

C>>Не надо использовать lazy-коллекции.
D>Сразу eager лепить чтоли ?
Угу. Но если хочется, то в Lombok можно исключать поля из toString/hash: https://projectlombok.org/features/ToString

Хотя тут отдельный вопрос — нафиг hashCode вообще нужен, если в него не входят все поля? Он получается бессмысленным.

C>>Вообще-то, Lombok работает через документированный интерфейс агентов инструментирования: https://docs.oracle.com/en/java/javase/11/docs/api/java.instrument/java/lang/instrument/package-summary.html

D>Может в более свежих JDK с этим стало получше и/или это нужно не для всех аннотаций.
По факту, Lombok используется настолько широко, что уже не сломается. Или починится крайне быстро.
Sapienti sat!
Re[21]: Через год-два .NET Core потеснит Java на рынке enter
От: takTak  
Дата: 23.04.20 05:56
Оценка: +1
T>>разница от дотнет в том, что в случае явы нужно тащить технические концепции в код, который просто должен вывести параллельно список букв, в дотнете необходимости в этом нет

vsb>Какие концепции? ForkJoinPool? Ну оно же не на магии работает. Естественно надо тащить.


так ведь я тоже мог бы написать

            string[] s1 = { "1", "2", "3", "4", "5", "6" };

            ThreadPool.SetMaxThreads(2, 2);

            IEnumerable<string> source = s1.ToList();
            using (CountdownEvent e = new CountdownEvent(1))
            {
                // fork work:
                foreach (var element in source)
                {
                    // Dynamically increment signal count.
                    e.AddCount();
                    ThreadPool.QueueUserWorkItem(delegate (object state)
                    {
                        try
                        {
                            Console.WriteLine("Item: " + element + "Thread " + Thread.CurrentThread.ManagedThreadId);
                        }
                        finally
                        {
                            e.Signal();
                        }
                    },
                     element);
                }
                e.Signal();

                // The first element could be run on this thread.

                // Join with work.
                e.Wait();
            }


однако мне больше нравится
            new List<string>() { "1", "2", "3", "4", "5", "6" }
                .AsParallel()
                .WithDegreeOfParallelism(2)
                .ForAll((entry) => {
                                        Console.WriteLine("[Task {0} : Thread {1}, Entry: {2}]", Task.CurrentId, Thread.CurrentThread.ManagedThreadId, entry); 
                                    });


потому что в майкрософте решили, что если написать абстракцию в виде task parallel library, то жить всем станет проще, на яве такой абстракции нет, поэтому я и вижу и пулы потоков и и их блокировку в то время, как я просто-напросто хотел параллельно обработать массив строк

все остальные мои старые вопросы подводили к мысли, что какая-то такая абстракция облегчала бы жизнь и в яве
Re[22]: Через год-два .NET Core потеснит Java на рынке enter
От: Cyberax Марс  
Дата: 23.04.20 07:22
Оценка: +1
Здравствуйте, takTak, Вы писали:

T> ThreadPool.SetMaxThreads(2, 2);

Повбывав бы.
Sapienti sat!
Re[19]: Через год-два .NET Core потеснит Java на рынке enterprise решений
От: Dziman США http://github.com/Dziman
Дата: 23.04.20 08:19
Оценка:
Здравствуйте, Cyberax, Вы писали:

C>Здравствуйте, Dziman, Вы писали:


D>>>>- сломанная навигация: как найти использование no-arg или all-arg конструкторов

C>>>Переходим на "file structure", там все конструкторы будут развёрнуты. Находим нужный элемент и ищем использование.
D>>ОК, можно. Но сравни с Cmd+Click/Cmd+B(GoTo) из кода
C>Это если конструктор на экране перед глазами, а не затерялся в простыне getter/setter'ов.
Так заведено что конструкторы обычно не теряются среди, а плавают сверху.

C>Кстати, насколько я помню, рефакторинг "добавить поле" там тоже работал. Сейчас лень ставить IDEA.

Т.е. просто руками добавить филд(набрав private (final) ...) уже нельзя. А также переместив декларацию филда на 3 строчки вверх, надо поменять 100500 мест где вызывается конструктор сгенерированный ломбоком?

C>>>Не надо так использовать Spring. Это плохой, негодный код.

D>>А как надо? @Autowired?
C>Надо использовать внешнюю конфигурацию.
Т.е. одной рукой ты за искоренение бойлерплейта(Lombok), а другой за(внешняя конфигурация и явное конструирование спринговских компонентов)

D>>>>Это что сразу всплыло в памяти

C>>>Не надо использовать lazy-коллекции.
D>>Сразу eager лепить чтоли ?
C>Угу.
Ты типа серьезно? Или у тебя в проектах для каждого сервиса или юзкейса свой @Entity?
C>Но если хочется, то в Lombok можно исключать поля из toString/hash: https://projectlombok.org/features/ToString
Естественно можно, но в реальности 99% разработчиков вхерачат дефолтный. И/или с течением времени туда подобавляются все филды потому что "вот тут надо ешё и это в строку вывести"

C>Хотя тут отдельный вопрос — нафиг hashCode вообще нужен, если в него не входят все поля? Он получается бессмысленным.

С порно

C>>>Вообще-то, Lombok работает через документированный интерфейс агентов инструментирования: https://docs.oracle.com/en/java/javase/11/docs/api/java.instrument/java/lang/instrument/package-summary.html

D>>Может в более свежих JDK с этим стало получше и/или это нужно не для всех аннотаций.
C>По факту, Lombok используется настолько широко, что уже не сломается. Или починится крайне быстро.
Миллионы мух ;(
Re[3]: Через год-два .NET Core потеснит Java на рынке enterprise решений
От: kov_serg Россия  
Дата: 23.04.20 08:29
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>Вообще, недавно услышал мысль что гуглу не нравится, что андроид использует java.

AA>Быть может это выступление было для того, чтобы заронить зерно сомнений в джавистов?
Им же теперь нравится kotlin
Re[20]: Через год-два .NET Core потеснит Java на рынке enterprise решений
От: Mamut Швеция http://dmitriid.com
Дата: 23.04.20 11:57
Оценка: +1
C>>По факту, Lombok используется настолько широко, что уже не сломается. Или починится крайне быстро.
D>Миллионы мух ;(

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

Тем временем в ./build/generated/source/apt/main/com.<organisation>

Было

@Value.Immutable
@JsonDeserialize(builder = com.<organisation>.entities.ImmutableContact.Builder.class)
public interface Contact {

    Optional<String> name();

    Optional<String> phoneNumber();

    Optional<String> address();

    Optional<String> email();
}


Стало (Если бы такой генерации кода не было, а все приходилось писать ручками, Java очень быстро обзавелась бы вменяемыми синтаксическими конструкциями)

  393 строчки кода
package com.<organisation>.entities;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.MoreObjects;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.google.errorprone.annotations.Var;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.CheckReturnValue;
import javax.annotation.Nullable;
import javax.annotation.ParametersAreNonnullByDefault;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.NotThreadSafe;
import org.immutables.value.Generated;

/**
 * Immutable implementation of {@link Contact}.
 * <p>
 * Use the builder to create immutable instances:
 * {@code ImmutableContact.builder()}.
 */
@Generated(from = "Contact", generator = "Immutables")
@SuppressWarnings({"all"})
@ParametersAreNonnullByDefault
@javax.annotation.processing.Generated("org.immutables.processor.ProxyProcessor")
@Immutable
@CheckReturnValue
public final class ImmutableContact implements Contact {
  private final @Nullable String name;
  private final @Nullable String phoneNumber;
  private final @Nullable String address;
  private final @Nullable String email;

  private ImmutableContact(
      @Nullable String name,
      @Nullable String phoneNumber,
      @Nullable String address,
      @Nullable String email) {
    this.name = name;
    this.phoneNumber = phoneNumber;
    this.address = address;
    this.email = email;
  }

  /**
   * @return The value of the {@code name} attribute
   */
  @JsonProperty("name")
  @Override
  public Optional<String> name() {
    return Optional.ofNullable(name);
  }

  /**
   * @return The value of the {@code phoneNumber} attribute
   */
  @JsonProperty("phoneNumber")
  @Override
  public Optional<String> phoneNumber() {
    return Optional.ofNullable(phoneNumber);
  }

  /**
   * @return The value of the {@code address} attribute
   */
  @JsonProperty("address")
  @Override
  public Optional<String> address() {
    return Optional.ofNullable(address);
  }

  /**
   * @return The value of the {@code email} attribute
   */
  @JsonProperty("email")
  @Override
  public Optional<String> email() {
    return Optional.ofNullable(email);
  }

  /**
   * Copy the current immutable object by setting a <i>present</i> value for the optional {@link Contact#name() name} attribute.
   * @param value The value for name
   * @return A modified copy of {@code this} object
   */
  public final ImmutableContact withName(String value) {
    @Nullable String newValue = Objects.requireNonNull(value, "name");
    if (Objects.equals(this.name, newValue)) return this;
    return new ImmutableContact(newValue, this.phoneNumber, this.address, this.email);
  }

  /**
   * Copy the current immutable object by setting an optional value for the {@link Contact#name() name} attribute.
   * An equality check is used on inner nullable value to prevent copying of the same value by returning {@code this}.
   * @param optional A value for name
   * @return A modified copy of {@code this} object
   */
  public final ImmutableContact withName(Optional<String> optional) {
    @Nullable String value = optional.orElse(null);
    if (Objects.equals(this.name, value)) return this;
    return new ImmutableContact(value, this.phoneNumber, this.address, this.email);
  }

  /**
   * Copy the current immutable object by setting a <i>present</i> value for the optional {@link Contact#phoneNumber() phoneNumber} attribute.
   * @param value The value for phoneNumber
   * @return A modified copy of {@code this} object
   */
  public final ImmutableContact withPhoneNumber(String value) {
    @Nullable String newValue = Objects.requireNonNull(value, "phoneNumber");
    if (Objects.equals(this.phoneNumber, newValue)) return this;
    return new ImmutableContact(this.name, newValue, this.address, this.email);
  }

  /**
   * Copy the current immutable object by setting an optional value for the {@link Contact#phoneNumber() phoneNumber} attribute.
   * An equality check is used on inner nullable value to prevent copying of the same value by returning {@code this}.
   * @param optional A value for phoneNumber
   * @return A modified copy of {@code this} object
   */
  public final ImmutableContact withPhoneNumber(Optional<String> optional) {
    @Nullable String value = optional.orElse(null);
    if (Objects.equals(this.phoneNumber, value)) return this;
    return new ImmutableContact(this.name, value, this.address, this.email);
  }

  /**
   * Copy the current immutable object by setting a <i>present</i> value for the optional {@link Contact#address() address} attribute.
   * @param value The value for address
   * @return A modified copy of {@code this} object
   */
  public final ImmutableContact withAddress(String value) {
    @Nullable String newValue = Objects.requireNonNull(value, "address");
    if (Objects.equals(this.address, newValue)) return this;
    return new ImmutableContact(this.name, this.phoneNumber, newValue, this.email);
  }

  /**
   * Copy the current immutable object by setting an optional value for the {@link Contact#address() address} attribute.
   * An equality check is used on inner nullable value to prevent copying of the same value by returning {@code this}.
   * @param optional A value for address
   * @return A modified copy of {@code this} object
   */
  public final ImmutableContact withAddress(Optional<String> optional) {
    @Nullable String value = optional.orElse(null);
    if (Objects.equals(this.address, value)) return this;
    return new ImmutableContact(this.name, this.phoneNumber, value, this.email);
  }

  /**
   * Copy the current immutable object by setting a <i>present</i> value for the optional {@link Contact#email() email} attribute.
   * @param value The value for email
   * @return A modified copy of {@code this} object
   */
  public final ImmutableContact withEmail(String value) {
    @Nullable String newValue = Objects.requireNonNull(value, "email");
    if (Objects.equals(this.email, newValue)) return this;
    return new ImmutableContact(this.name, this.phoneNumber, this.address, newValue);
  }

  /**
   * Copy the current immutable object by setting an optional value for the {@link Contact#email() email} attribute.
   * An equality check is used on inner nullable value to prevent copying of the same value by returning {@code this}.
   * @param optional A value for email
   * @return A modified copy of {@code this} object
   */
  public final ImmutableContact withEmail(Optional<String> optional) {
    @Nullable String value = optional.orElse(null);
    if (Objects.equals(this.email, value)) return this;
    return new ImmutableContact(this.name, this.phoneNumber, this.address, value);
  }

  /**
   * This instance is equal to all instances of {@code ImmutableContact} that have equal attribute values.
   * @return {@code true} if {@code this} is equal to {@code another} instance
   */
  @Override
  public boolean equals(@Nullable Object another) {
    if (this == another) return true;
    return another instanceof ImmutableContact
        && equalTo((ImmutableContact) another);
  }

  private boolean equalTo(ImmutableContact another) {
    return Objects.equals(name, another.name)
        && Objects.equals(phoneNumber, another.phoneNumber)
        && Objects.equals(address, another.address)
        && Objects.equals(email, another.email);
  }

  /**
   * Computes a hash code from attributes: {@code name}, {@code phoneNumber}, {@code address}, {@code email}.
   * @return hashCode value
   */
  @Override
  public int hashCode() {
    @Var int h = 5381;
    h += (h << 5) + Objects.hashCode(name);
    h += (h << 5) + Objects.hashCode(phoneNumber);
    h += (h << 5) + Objects.hashCode(address);
    h += (h << 5) + Objects.hashCode(email);
    return h;
  }

  /**
   * Prints the immutable value {@code Contact} with attribute values.
   * @return A string representation of the value
   */
  @Override
  public String toString() {
    return MoreObjects.toStringHelper("Contact")
        .omitNullValues()
        .add("name", name)
        .add("phoneNumber", phoneNumber)
        .add("address", address)
        .add("email", email)
        .toString();
  }

  /**
   * Creates an immutable copy of a {@link Contact} value.
   * Uses accessors to get values to initialize the new immutable instance.
   * If an instance is already immutable, it is returned as is.
   * @param instance The instance to copy
   * @return A copied immutable Contact instance
   */
  public static ImmutableContact copyOf(Contact instance) {
    if (instance instanceof ImmutableContact) {
      return (ImmutableContact) instance;
    }
    return ImmutableContact.builder()
        .from(instance)
        .build();
  }

  /**
   * Creates a builder for {@link ImmutableContact ImmutableContact}.
   * @return A new ImmutableContact builder
   */
  public static ImmutableContact.Builder builder() {
    return new ImmutableContact.Builder();
  }

  /**
   * Builds instances of type {@link ImmutableContact ImmutableContact}.
   * Initialize attributes and then invoke the {@link #build()} method to create an
   * immutable instance.
   * <p><em>{@code Builder} is not thread-safe and generally should not be stored in a field or collection,
   * but instead used immediately to create instances.</em>
   */
  @Generated(from = "Contact", generator = "Immutables")
  @NotThreadSafe
  public static final class Builder {
    private @Nullable String name;
    private @Nullable String phoneNumber;
    private @Nullable String address;
    private @Nullable String email;

    private Builder() {
    }

    /**
     * Fill a builder with attribute values from the provided {@code Contact} instance.
     * Regular attribute values will be replaced with those from the given instance.
     * Absent optional values will not replace present values.
     * @param instance The instance from which to copy values
     * @return {@code this} builder for use in a chained invocation
     */
    @CanIgnoreReturnValue 
    public final Builder from(Contact instance) {
      Objects.requireNonNull(instance, "instance");
      Optional<String> nameOptional = instance.name();
      if (nameOptional.isPresent()) {
        name(nameOptional);
      }
      Optional<String> phoneNumberOptional = instance.phoneNumber();
      if (phoneNumberOptional.isPresent()) {
        phoneNumber(phoneNumberOptional);
      }
      Optional<String> addressOptional = instance.address();
      if (addressOptional.isPresent()) {
        address(addressOptional);
      }
      Optional<String> emailOptional = instance.email();
      if (emailOptional.isPresent()) {
        email(emailOptional);
      }
      return this;
    }

    /**
     * Initializes the optional value {@link Contact#name() name} to name.
     * @param name The value for name
     * @return {@code this} builder for chained invocation
     */
    @CanIgnoreReturnValue 
    public final Builder name(String name) {
      this.name = Objects.requireNonNull(name, "name");
      return this;
    }

    /**
     * Initializes the optional value {@link Contact#name() name} to name.
     * @param name The value for name
     * @return {@code this} builder for use in a chained invocation
     */
    @CanIgnoreReturnValue 
    @JsonProperty("name")
    public final Builder name(Optional<String> name) {
      this.name = name.orElse(null);
      return this;
    }

    /**
     * Initializes the optional value {@link Contact#phoneNumber() phoneNumber} to phoneNumber.
     * @param phoneNumber The value for phoneNumber
     * @return {@code this} builder for chained invocation
     */
    @CanIgnoreReturnValue 
    public final Builder phoneNumber(String phoneNumber) {
      this.phoneNumber = Objects.requireNonNull(phoneNumber, "phoneNumber");
      return this;
    }

    /**
     * Initializes the optional value {@link Contact#phoneNumber() phoneNumber} to phoneNumber.
     * @param phoneNumber The value for phoneNumber
     * @return {@code this} builder for use in a chained invocation
     */
    @CanIgnoreReturnValue 
    @JsonProperty("phoneNumber")
    public final Builder phoneNumber(Optional<String> phoneNumber) {
      this.phoneNumber = phoneNumber.orElse(null);
      return this;
    }

    /**
     * Initializes the optional value {@link Contact#address() address} to address.
     * @param address The value for address
     * @return {@code this} builder for chained invocation
     */
    @CanIgnoreReturnValue 
    public final Builder address(String address) {
      this.address = Objects.requireNonNull(address, "address");
      return this;
    }

    /**
     * Initializes the optional value {@link Contact#address() address} to address.
     * @param address The value for address
     * @return {@code this} builder for use in a chained invocation
     */
    @CanIgnoreReturnValue 
    @JsonProperty("address")
    public final Builder address(Optional<String> address) {
      this.address = address.orElse(null);
      return this;
    }

    /**
     * Initializes the optional value {@link Contact#email() email} to email.
     * @param email The value for email
     * @return {@code this} builder for chained invocation
     */
    @CanIgnoreReturnValue 
    public final Builder email(String email) {
      this.email = Objects.requireNonNull(email, "email");
      return this;
    }

    /**
     * Initializes the optional value {@link Contact#email() email} to email.
     * @param email The value for email
     * @return {@code this} builder for use in a chained invocation
     */
    @CanIgnoreReturnValue 
    @JsonProperty("email")
    public final Builder email(Optional<String> email) {
      this.email = email.orElse(null);
      return this;
    }

    /**
     * Builds a new {@link ImmutableContact ImmutableContact}.
     * @return An immutable instance of Contact
     * @throws java.lang.IllegalStateException if any required attributes are missing
     */
    public ImmutableContact build() {
      return new ImmutableContact(name, phoneNumber, address, email);
    }
  }
}


dmitriid.comGitHubLinkedIn
Re[22]: Через год-два .NET Core потеснит Java на рынке enter
От: vsb Казахстан  
Дата: 23.04.20 12:27
Оценка:
Здравствуйте, takTak, Вы писали:

T>потому что в майкрософте решили, что если написать абстракцию в виде task parallel library, то жить всем станет проще, на яве такой абстракции нет, поэтому я и вижу и пулы потоков и и их блокировку в то время, как я просто-напросто хотел параллельно обработать массив строк


T>все остальные мои старые вопросы подводили к мысли, что какая-то такая абстракция облегчала бы жизнь и в яве


В Java ForkJoinPool на практике придёт сверху с более высоких слоёв, которые лучше знают, сколько потоков можно выделить. И запрос будет обрабатываться в контексте этого пула. И он автоматически будет использовать именно его. Т.е. юзер коду вообще не надо думать ни про какие потоки или пулы, за него уже подумали сверху. А соседний запрос другой пул. Или общий. Важно то, что код пользователя про это не заботится. Он просто говорит, хочу обрабатывать параллельно. А в .NET мне придётся какую-то конфигурацию динамическую создавать, прокидывать там всё только для того, чтобы параметры тред пула каждой операции передавать. Это очень неудобно.
Отредактировано 23.04.2020 12:29 vsb . Предыдущая версия .
Re: С того времени уже прошло 3 года
От: Явь-Истъ Земля  
Дата: 23.04.20 12:40
Оценка: +1
Статья 2017 года. Два года прошло еще в прошлом году. Что либо изменилось? Нет конечно.
На хабре так вообще, в трендах молиться на питон и раст.
Люди всегда хотят чего-то нового, а продавцы всегда готовы что-то новенькое продать.
Проблема в том, что зачастую в этом нововведении резона почти нет. Зато вроде как движуха какая-то идет — конференции, восторженные лозунги, сообщества.
Re[23]: Через год-два .NET Core потеснит Java на рынке enter
От: Serginio1 СССР https://habrahabr.ru/users/serginio1/topics/
Дата: 23.04.20 13:24
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>В Java ForkJoinPool на практике придёт сверху с более высоких слоёв, которые лучше знают, сколько потоков можно выделить. И запрос будет обрабатываться в контексте этого пула. И он автоматически будет использовать именно его. Т.е. юзер коду вообще не надо думать ни про какие потоки или пулы, за него уже подумали сверху. А соседний запрос другой пул. Или общий. Важно то, что код пользователя про это не заботится. Он просто говорит, хочу обрабатывать параллельно. А в .NET мне придётся какую-то конфигурацию динамическую создавать, прокидывать там всё только для того, чтобы параметры тред пула каждой операции передавать. Это очень неудобно.

В большинстве случаев это так и на C#. Но вот когда у тебя есть дополнительная информация, о которой ни компилятор ни планировщик не знает, ты можешь сделать подсказки и приоритеты, что бы не было драки за потоки
и солнце б утром не вставало, когда бы не было меня
Re[23]: Через год-два .NET Core потеснит Java на рынке enter
От: takTak  
Дата: 23.04.20 13:55
Оценка:
T>>потому что в майкрософте решили, что если написать абстракцию в виде task parallel library, то жить всем станет проще, на яве такой абстракции нет, поэтому я и вижу и пулы потоков и и их блокировку в то время, как я просто-напросто хотел параллельно обработать массив строк

T>>все остальные мои старые вопросы подводили к мысли, что какая-то такая абстракция облегчала бы жизнь и в яве


vsb>В Java ForkJoinPool на практике придёт сверху с более высоких слоёв, которые лучше знают, сколько потоков можно выделить. И запрос будет обрабатываться в контексте этого пула. И он автоматически будет использовать именно его. Т.е. юзер коду вообще не надо думать ни про какие потоки или пулы, за него уже подумали сверху. А соседний запрос другой пул. Или общий. Важно то, что код пользователя про это не заботится. Он просто говорит, хочу обрабатывать параллельно. А в .NET мне придётся какую-то конфигурацию динамическую создавать, прокидывать там всё только для того, чтобы параметры тред пула каждой операции передавать. Это очень неудобно.



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

приведёнными примерами я лишь показал, что на дотнете ты можешь писать на низкоуровенвом уровне, как на яве, и , кроме того, на более высоуровневом, и , кроме того, ты можешь написать низкоуровневый код, поместить его в extension method и использовать его из более высокоуровневого, т.е. возможностей ровно в два раза больше
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.