JavaRush /Java блог /Random /Кофе-брейк #221. Три способа, как найти элемент в массиве...

Кофе-брейк #221. Три способа, как найти элемент в массиве Java. Что такое Java Thread Local и как его использовать

Статья из группы Random

Три способа, как найти элемент в массиве Java

Источник: Asyncq Эта публикация поможет вам лучше узнать, какие существуют способы поиска элемента в массиве в Java. Кофе-брейк #221. Три способа, как найти элемент в массиве Java. Что такое Java Thread Local и как его использовать - 1Поиск определенного элемента в наборе значений — очень распространенная и часто используемая операция в разработке программного обеспечения. Существуют разные подходы к решению этой проблемы, от простых до оптимизированных. Давайте их рассмотрим.

Вводные данные

Вводный массив содержит примитивные данные идентификаторов, и нам нужно узнать, содержится ли в нем id->3.

int[] ids = { 1,2,13,14,15,3,10,11,12,4,5,6,7,8,9 };
int inputId = 3;

Способ 1 (простой)

  1. Посещаем все элементы массива, поочередно по одному элементу.
  2. Дополнительно отслеживаем состояние целевого элемента, если он существует в массиве.
  3. Как только мы находим этот элемент, то переключаем статус с false на true.
  4. После завершения цикла возвращаем флаг состояния.

boolean valExist = false;
for (int id : ids) {
   if (inputId == id) {
             valExist = true;
   }
}
return valExist;
Это решение работает, но оно не очень эффективно. Если вы посмотрите на условие if, то поймете, что мы проверяем это условие для всех элементов. Допустим, элемент, который мы ищем, является первым элементом, но наш цикл все равно продолжит выполняться для всех элементов. Здесь разумнее было бы выйти из цикла, как только мы найдем элемент. Сделав это, мы бы сэкономили на вычислениях, когда искомый элемент находится не в последней позиции.

boolean valExist = false;
for (int id : ids) {
    if (inputId == id) {
                valExist = true;
                break;
     }
}
return valExist;
Можно сделать код еще более кратким, используя return. Мы можем вернуть true, как только увидим искомый элемент, в противном случае возвращаем false, как только цикл завершится. И нам не нужно создавать и поддерживать переменную состояния.

for (int id : ids) {
      if (inputId == id) {
                return true;
       }
  }
  return false;

Способ 2

  1. Мы можем использовать ArrayList, содержащий метод, который по умолчанию ищет целевой элемент в списке.
  2. Поскольку этот метод предоставляется List, нам нужно преобразовать наш примитивный массив в список.
  3. Мы можем использовать одну лямбда-строку, которая преобразует примитив в тип объекта и создает из него список (list).
    
    return Arrays.asList(Arrays.stream(ids).boxed().toArray())
                  .contains(inputId);
    
  4. Мы можем использовать Stream API Java 8, чтобы сделать наш код функциональным и намного короче.
  5. Чтобы понять, как Stream API работают с потоками, нам нужно преобразовать наш вводной массив в поток.
  6. Arrays.stream получает вводный массив и преобразует его в потоки.
  7. Теперь, когда у нас есть потоки, мы можем использовать множество полезных методов, один из которых — anyMatch. Он возвращает элемент, соответствующий предикату (id == inputId).
  8. Все это делает наш код намного короче и легче для чтения.
    
    return Arrays.stream(ids)
              .anyMatch(id -> id == inputId);
    

Способ 3 (оптимизированный)

Да, показанный выше код работает и его легко читать, но нам все равно нужно посещать и сравнивать каждый элемент в потоке.
  1. Если с памятью нет проблем и мы хотим оптимизировать вычисления, то одна из вещей, которые мы можем здесь сделать, — это создать набор из вводного массива.
  2. Мы снова можем использовать код функционального стиля для преобразования примитивного массива в Set.
  3. Теперь, когда у нас есть Set, мы можем искать элемент в течение постоянного время.
S

et<Integer> idsSet = Arrays.stream(ids).boxed().collect(Collectors.toSet());
return idsSet.contains(inputId);

Бонус

Поиск одного элемента можно считать обычной операцией, но более распространенным все же является поиск нескольких элементов в массиве. В данном случае, если мы не используем Set, у нас будет два цикла, а временная сложность увеличится до умножения длины двух коллекций. Ниже приведен пример, в котором мы преобразуем один из массивов как набор (set), а затем перебираем другой массив и выполняем поиск в операции набора. Делая это, мы увеличиваем память и при этом экономим на вычислениях.

int[] targetIds = { 1, 3, 6, 88, 999, 34, 44, 55};
int[] ids = { 1,2,13,14,15,3,10,11,12,4,5,6,7,8,9 };
 
 
Set<Integer> idsSet = Arrays.stream(ids).boxed().collect(Collectors.toSet());
return Arrays.stream(targetIds)
            .boxed()
            .filter(id -> !idsSet.contains(id))
            .mapToInt(a -> a)
            .toArray();

Что такое Java Thread Local и как его использовать

Источник: Medium В данной статье мы рассмотрим Java Thread Local и способы его эффективного использования в ваших Java-приложениях. Кофе-брейк #221. Три способа, как найти элемент в массиве Java. Что такое Java Thread Local и как его использовать - 2Java Thread Local — это мощная функция, которая позволяет разработчикам создавать переменные только для определенного потока. Это означает, что у каждого потока может быть своя копия переменной, и изменения, внесенные в переменную в одном потоке, не повлияют на ее значение в другом потоке.

Что такое Thread Local

Thread Local — это класс в API Java, который позволяет создавать переменные, локальные для определенного потока. То есть, каждый поток имеет свою собственную копию переменной, и изменения, внесенные в переменную в одном потоке, не влияют на ее значение в другом потоке. Это делает Thread Local идеальным решением для хранения данных, специфичных для потока, таких как информация об аутентификации пользователя, соединения с базой данных или любая другая информация, относящаяся к потоку.

Как работает Thread Local в Java

Чтобы использовать Thread Local в вашем Java-приложении, сначала нужно создать экземпляр класса Thread Local. Это можно сделать, вызвав конструктор ThreadLocal, который и создаст новый экземпляр этого класса. Далее, создав объект Thread Local, вы можете использовать его для хранения и извлечения данных, специфичных для каждого потока. Вот пример того, как использовать Thread Local в вашем Java-приложении:

public class MyThreadLocalClass {
  private static final ThreadLocal<String> threadLocal = new ThreadLocal<>();

  public static void set(String value) {
    threadLocal.set(value);
  }

  public static String get() {
    return threadLocal.get();
  }
}
В этом примере мы создали объект Thread Local по имени threadLocal типа String. Мы также создали два метода: set() и get(), которые позволяют нам сохранять и извлекать значение переменной Thread Local. Чтобы сохранить значение в переменной Thread Local, мы просто вызываем метод set() и передаем значение, которое хотим сохранить. Например, мы можем вызвать MyThreadLocalClass.set("Hello, World!") для сохранения строки “Hello, World!” в переменной Thread Local. Чтобы получить значение переменной Thread Local, мы просто вызываем метод get(). Например, мы можем вызвать String value = MyThreadLocalClass.get() для получения значения переменной Thread Local.

Рекомендации по работе с Thread Local

Хотя Thread Local может стать мощным инструментом в ваших Java-приложениях, важно использовать его правильно, чтобы избежать потенциальных проблем. Вот несколько рекомендаций, которые следует учитывать при использовании Thread Local:
  1. Используйте Thread Local только при необходимости: лишь для данных, относящихся к потоку. Если данные не относятся к конкретному потоку, они должны храниться другим способом.
  2. Избегайте чрезмерного использования памяти: Thread Local может потреблять значительный объем памяти, если не использовать его осторожно. Обязательно очищайте переменные Thread Local, когда они больше не нужны, чтобы избежать чрезмерного использования памяти.
  3. Используйте Thread Local с осторожностью в многопоточных средах: важно понимать потенциальные риски и ограничения. Обязательно тщательно протестируйте свой код, чтобы убедиться, что Thread Local работает должным образом в вашей конкретной среде.

Заключение

Java Thread Local — отличный инструмент, позволяющий разработчикам создавать переменные только для определенного потока. Используя Thread Local, вы можете хранить данные, относящиеся к потоку, например информацию об аутентификации пользователя, подключения к базе данных или другую информацию, относящуюся к потоку. Хотя Thread Local может быть мощным инструментом, важно использовать его правильно, чтобы избежать потенциальных проблем. Следуя рекомендациям и тестируя свой код, вы сможете эффективно его использовать для повышения производительности и надежности ваших Java-приложений.
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ