- Вы не сбрасываете переменную
value
в своем окончательном forl oop, поэтому вы получаете постоянно увеличивающиеся числа в вашей печати, заканчивающиеся на 34.56
. Вам нужно одно значение для каждой записи materialArray, поэтому сразу после for (i = 0; i < materialArray.length; i++) {
вам нужно будет value = 0
. - Вы используете
materialArray[i].contains(matnr[j])
- это спрашивает, является ли matnr [j] подстрокой materialArray [я]. Кажется довольно очевидным, что вы хотели вместо этого equals
. Незначительная нить и здесь не ломается, но, тем не менее, это ошибка. - Ваш принтер будет печатать каждый раз, когда индивидуальная запись совпадает, и ничего не печатает после того, как вы пройдете весь список, что приведет к этому странному выводу . Предположительно ваше намерение состоит в том, чтобы позволить внутреннему l oop (
for (int j = 0; j < matnr.length; j++)
) завершиться, а ЗАТЕМ вы хотите распечатать. Таким образом, ваш оператор sysout должен быть сдвинут на две строки вниз, после закрывающей скобки внутреннего для l oop. Совместите это со сбросом value
и ...
Value1 >>> 14.56
Value1 >>> 11.0
Value1 >>> 9.0
NB: Вторая проблема - это ошибки округления. Вы в основном должны никогда toString () или иным образом напрямую печатать значение с плавающей запятой или двойное значение. Если вы это сделаете, вы получите шаткую странность, например, 19.560000000000002
.
Если я попрошу вас, используя десятичную запись, записать результат «одна треть», вы должны округлить. Вы не можете написать бесконечную обработку 0,33333333, верно? Компьютеры (в частности, double и float) ничем не отличаются, но компьютеры считают двоичными, а не десятичными. Итак, компьютер должен немного округлить, а затем «визуализировать» имеющееся значение в десятичном формате, и отсюда возникает странность. Неточностей, вносимых этим округлением, невозможно избежать (по крайней мере, не с помощью удвоений и чисел с плавающей запятой), но обычно неточности не вкрадываются в соответствующее значение ваших чисел. Поэтому решение - ВСЕГДА направлять библиотеки при печати ваших чисел, сообщая им, сколько цифр вы ожидаете. Итак, сделайте это:
System.out.printf("Value1 >>> %.4f\n", value);
%.4f
сообщает принтеру печатать с не более чем 4 цифрами после точки, а printf
не переводит автоматически новую строку, поэтому \n
сообщает ему напечатайте эту новую строку явно.
Наконец, это вопрос этого стиля кода. Это можно сделать гораздо проще (и эффективнее) с помощью встроенных инструментов java, таких как HashMap
:
public static void main(String[] args) {
String[] matnr = new String[] { "16400", "56000", "56000", "50000", "16400" };
String[] lfimg = new String[] { "4.000", "5.000", "6.000", "9.000", "10.56" };
var values = new HashMap<String, Double>();
// load values into the map.
for (int i = 0; i < matnr.length; i++) {
double z = Double.parseDouble(lfimg[i]);
values.compute(matnr[i], (m, v) -> v == null ? z : v + z); // [1]
}
// print them to show it works
for (var e : values.entrySet()) {
System.out.printf("%s: %.4f\n", e.getKey(), e.getValue());
}
}
Ключевая строка - это строка с пометкой [1]
: в ней говорится: Чтобы вычислить значение для значения в текущей записи matnr
, если еще нет существующего значения (v будет нулевым), это просто соответствующая запись из lfimg
, а если есть существующее значение, это сумма того, что у нас было, плюс соответствующая запись из lfimg
.