Я потрапив у ситуацію, коли хочу використовувати змінні версії таких речей, як 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
вже згадувалося. Змінювані Double
s можна емулювати 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