JavaRush /Java блог /Random UA /Кава-брейк #221. Три способи, як знайти елемент у масиві ...

Кава-брейк #221. Три способи, як знайти елемент у масиві Java. Що таке Java Thread Local і як його використовувати

Стаття з групи Random UA

Три способи, як знайти елемент у масиві Java

Джерело: Asyncq Ця публікація допоможе вам краще дізнатися, які існують способи пошуку елемента в масиві Java. Кава-брейк #221.  Три способи, як знайти елемент у масиві Java.  Що таке Java Thread Local і як його використовувати?Пошук певного елемента в наборі значень — дуже поширена операція, що часто використовується в розробці програмного забезпечення. Існують різні підходи до вирішення цієї проблеми, від найпростіших до оптимізованих. Давайте їх розглянемо.

Вхідні дані

Вступний масив містить примітивні дані ідентифікаторів, і нам потрібно дізнатися, чи міститься в ньому 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 і як його використовувати?Java 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-додатків.
Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ