Een tijdje terug kwam ik een bug tegen in m'n code, dit heb ik kunnen reduceren tot het volgende waar het probleem optreedt. Ik heb er al een tijd mee lopen stoeien, maar het waarom ontgaat me.
Het doel is om een threshold toe te passen op een rijtje getallen, getallen die niet voldoen worden NaN, dat werkt. En dan wordt er nog een flag bijgehouden om te zien of er overschrijdingen waren. Het wijzigen van die flag geeft problemen.
De output van het programma verwart mij:
Setting the flag to true: 4.0
Setting the flag to true: 5.0
Result: [1.0, 2.0, 3.0, NaN, NaN]
Flag: true //mooi!
Setting the flag to true: 4.1
Setting the flag to true: 5.1
Result: [1.1, 2.1, 2.9, NaN, NaN]
Flag: false //heh?
Ik snap niet wat er nou anders is aan die tweede case, waarbij het flag object gemaakt wordt in de methode.
Met Java 10.0.2 overigens (Ik zat nog op 8, maar dat werkte hetzelfde).
Met StreamEx (https://github.com/amaembo/streamex) ook hetzelfde resultaat.
Inlinen van de objecten die het array in gaan op line 31 hielp (gelukkig) ook niet.
Tips?
Het doel is om een threshold toe te passen op een rijtje getallen, getallen die niet voldoen worden NaN, dat werkt. En dan wordt er nog een flag bijgehouden om te zien of er overschrijdingen waren. Het wijzigen van die flag geeft problemen.
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
| public class Why { public static void main(String[] args) { System.out.println(System.getProperty("java.version")); // Works as expected Stream<Double> data = Stream.of(Double.valueOf(1.0), Double.valueOf(2.0), Double.valueOf(3.0), Double.valueOf(4.0), Double.valueOf(5.0)); Flag flag = new Flag(); System.out.println("Result: " + data.map(i -> valueOverThree(i, flag)).collect(Collectors.toList())); System.out.println("Flag: " + flag.getFlag() + "\n"); // Flag remains false... Why? final Stream<Double> data2 = Stream.of(Double.valueOf(1.1), Double.valueOf(2.1), Double.valueOf(2.9), Double.valueOf(4.1), Double.valueOf(5.1)); Flag flag2 = new Flag(); Stream<Double> result = data2.map(a -> valueOverThree(a, flag2)); Object[] outputWrapper = valueOverThreeWithFlag(result); System.out.println("Result: " + ((Stream<Double>) (outputWrapper[0])).collect(Collectors.toList())); System.out.println("Flag: " +outputWrapper[1]); } public static Object[] valueOverThreeWithFlag(final Stream<Double> data) { Flag flag = new Flag(); flag.setFlag(false); return new Object[] { data.map(a -> valueOverThree(a, flag)), Boolean.valueOf(flag.getFlag()) }; } static Double valueOverThree(final Double input, Flag flag) { if (input.doubleValue() > 3.0) { flag.setFlag(true); System.out.println("Setting the flag to true: " + input); return Double.NaN; } return input; } } //De genoemde Flag public class Flag { private boolean flag; /** * @return the flag */ public boolean getFlag() { return flag; } /** * @param flag the flag to set */ public void setFlag(boolean flag) { this.flag = flag; } } |
De output van het programma verwart mij:
Setting the flag to true: 4.0
Setting the flag to true: 5.0
Result: [1.0, 2.0, 3.0, NaN, NaN]
Flag: true //mooi!
Setting the flag to true: 4.1
Setting the flag to true: 5.1
Result: [1.1, 2.1, 2.9, NaN, NaN]
Flag: false //heh?
Ik snap niet wat er nou anders is aan die tweede case, waarbij het flag object gemaakt wordt in de methode.
Met Java 10.0.2 overigens (Ik zat nog op 8, maar dat werkte hetzelfde).
Met StreamEx (https://github.com/amaembo/streamex) ook hetzelfde resultaat.
Inlinen van de objecten die het array in gaan op line 31 hielp (gelukkig) ook niet.
Tips?
"Take the risk of thinking for yourself. Much more happiness, truth, beauty, and wisdom will come to you that way." -Christopher Hitchens | In memoriam? 🏁 ipv kruis!