Я потрапив у ситуацію, коли хочу використовувати змінні версії таких речей, як Integer. Чи повинен я використовувати ці класи (нижче), чи Java щось вбудовано?
http://www.java2s.com/Code/Java/Data-Type/Amutableintwrapper.htm
Я потрапив у ситуацію, коли хочу використовувати змінні версії таких речей, як Integer. Чи повинен я використовувати ці класи (нижче), чи Java щось вбудовано?
http://www.java2s.com/Code/Java/Data-Type/Amutableintwrapper.htm
nкалоріями, яку можна виснажити / додати), може бути краще використовувати клас, названий після використання, (наприклад class FoodItem { int calories; }, тому що це зрозуміліше, а методи можуть за потреби буде додано пізніше.
intне працює, ніби його збільшують в одному методі, тоді значення не відображається в іншому методі.
Відповіді:
Ні, у Java їх немає вбудованих. І це не просто так. Використання змінних типів небезпечно, оскільки ними легко скористатися. Крім того, це дуже просто реалізувати. Наприклад, commons-lang має MutableInt.
Ви завжди можете обернути значення в масив, наприклад, int[] mutable = {1};якщо включення коду для змінного класу обгортки занадто громіздке.
Оскільки JDK 1.5 тепер має java java.util.concurrent.atomic.AtomicInteger
Це ціле число, що безпечно змінюється, приклад використання:
final AtomicInteger value = new AtomicInteger(0);
потім пізніше:
value.incrementAndGet();
Ось невеликий клас, який я створив для змінного цілого числа:
public class MutableInteger {
private int value;
public MutableInteger(int value) {
this.value = value;
}
public void set(int value) {
this.value = value;
}
public int intValue() {
return value;
}
}
Ви можете легко поширити це на будь-який інший примітив. Звичайно, як і всі інші кажуть, ви повинні використовувати його обережно.
MutableInteger, MutableDouble, і MutableStringт.д. , але замість того, щоб мати Mutable<Integer>, Mutable<Double>... Накладні пам'яті (використання Integerбільш intзазвичай не потрапляють в розрахунок. Але ви отримуєте єдиний, готовий до використання клас, який може впоратись з більшістю випадків (якщо ви хочете, щоб ваше ціле число було порівнянним або подібним, все одно вам потрібно підклас).
Ви можете використовувати nnnn [] як змінний об'єкт для будь-якого примітивного типу, як пропонує @Alexandre, у Java також є AtomicInteger та AtomicLong.
IMHO int, як правило, кращий вибір, ніж Integer, і його можна змінювати.
Чи можете ви отримати більш детальну інформацію про те, навіщо вам потрібен багаторазовий об’єкт, можливо, існує інший спосіб досягти того самого.
intзавжди змінюється, якщо тільки це також не булоfinal
Integer a = 4;тоді a = 5;дійсний код, але Integerйого не можна змінити.
Integerекземпляри не можна змінювати, навіть якщо посилання на них є, але це інший тип.
intне змінюється, тому що якщо ви передасте його методу, метод не зможе змінити своє значення і відобразити нове значення у виклику методу
AtomicIntegerвже згадувалося. Змінювані Doubles можна емулювати AtomicReference<Double>. Вже згадані попередження застосовуються, і це поганий стиль, але іноді у вас є такий код
double sum=0
for (Data data:someListGenerator())
sum+=data.getValue()
і хочете його переформатувати у функціональному стилі Java 8. Якщо код слідує цьому шаблону, але додає йому значної складності, може бути найбільш розумним перетворенням
AtomicReference<Double> sumref=new AtomicReference<>(0d);
someStreamGenerator().forEach(data->
sumref.set(sumref.get().doubleValue()+data.getValue()));
double sum=sumref.get().doubleValue();
Звичайно, це принаймні сумнівний стиль. Але я неодноразово потрапляв у ситуацію із скрученою петлею над ResultSetобчисленням і частково накопичуючи з неї три різні відомості. Це ускладнює перетворення коду у належний функціональний стиль. Перетворення кумулятивних частин за вищенаведеною схемою здалося мені розумним компромісом між чистим кодом та спрощеним рефакторингом.
someStreamGenerator().mapToDouble(Data::getValue).sum(). Навіть для накопичення трьох різних відомостей існує функціональний спосіб, використовуючи Stream.reduceабо Stream.collect. Я не бачу причин переробляти кожен цикл на функціональний фрагмент коду, але якщо ви хочете піти таким шляхом, вам слід пройти його до кінця.
forі foreachможуть бути частинами складних фреймворків, які функціонально переписуються, тому вам доведеться якось вирівняти решту коду навколо них.
Ви можете імпортувати пакет org.omg.CORBA (або просто потрібний вам клас), і в ньому ви можете використовувати класи Holder.
Наприклад, у ньому є "IntHolder", де поле, де воно зберігає ціле число, є загальнодоступним, що надає доступ до його модифікації.
public static void triple(IntHolder x){
x.value = 3 * x.value;
}
IntHolder mutableInt = new IntHolder(10);
triple(mutableInt);
System.out.println(mutableInt.value);
У ньому також є "LongHolder" та "DoubleHolder" та безліч інших, якими ви можете скористатися. Використовуйте з обережністю.
Ось API для нього: https://docs.oracle.com/javase/7/docs/api/org/omg/CORBA/package-summary.html