Modulo-operatøren i Java
1. Oversigt
I denne korte vejledning skal vi vise, hvad modulo-operatøren er, og hvordan vi kan bruge det med Java til nogle almindelige brugssager.
2. Modulo-operatøren
Lad os starte med manglerne ved enkel opdeling i Java.
Hvis operanderne på begge sider af divisionsoperatøren har type int, resultatet af operationen er et andet int:
@Test offentlig ugyldig nårIntegerDivision_thenLosesRemainder () {assertThat (11/4) .isEqualTo (2); }
Den samme division giver os et andet resultat, når mindst en af operanderne har typen flyde eller dobbelt:
@Test offentlig ugyldig nårDoubleDivision_thenKeepsRemainder () {assertThat (11 / 4.0) .isEqualTo (2.75); }
Vi kan se, at vi mister resten af en opdeling, når vi deler heltal.
Moduloperatoren giver os nøjagtigt denne rest:
@Test offentlig ugyldig nårModulo_thenReturnsRemainder () {assertThat (11% 4) .isEqualTo (3); }
Resten er, hvad der er tilbage efter at have divideret 11 (udbyttet) med 4 (deleren) - i dette tilfælde 3.
Af samme grund er en division med nul ikke mulig, det er ikke muligt at bruge modulo-operatoren, når argumentet til højre er nul.
Både delingen og modulo-operationen kaster et Aritmetisk undtagelse når vi prøver at bruge nul som højre side operand:
@Test (forventet = ArithmeticException.class) offentlig ugyldig nårDivisionByZero_thenArithmeticException () {dobbelt resultat = 1/0; } @Test (forventet = ArithmeticException.class) offentlig ugyldig nårModuloByZero_thenArithmeticException () {dobbelt resultat = 1% 0; }
3. Almindelige brugssager
Det mest almindelige anvendelsestilfælde for modulo-operatøren er at finde ud af, om et givet tal er ulige eller lige.
Hvis resultatet af moduloperationen mellem et hvilket som helst tal og to er lig med et, er det et ulige tal:
@Test offentlig ugyldig nårDivisorIsOddAndModulusIs2_thenResultIs1 () {assertThat (3% 2) .isEqualTo (1); }
På den anden side, hvis resultatet er nul (dvs. der er ingen rest), er det et lige antal:
@Test offentlig ugyldig nårDivisorIsEvenAndModulusIs2_thenResultIs0 () {assertThat (4% 2) .isEqualTo (0); }
En anden god anvendelse af modulo-operationen er at holde styr på indekset for det næste ledige sted i et cirkulært array.
I en simpel implementering af en cirkulær kø til int værdier, holdes elementerne i et array i fast størrelse.
Hver gang vi vil skubbe et element til vores cirkulære kø, beregner vi bare den næste ledige position ved at beregne modulo for antallet af emner, vi allerede har indsat plus 1 og køkapaciteten:
@Test offentligt ugyldigt nårItemsIsAddedToCircularQueue_thenNoArrayIndexOutOfBounds () {int QUEUE_CAPACITY = 10; int [] circularQueue = ny int [QUEUE_CAPACITY]; int itemsInserted = 0; for (int værdi = 0; værdi <1000; værdi ++) {int writeIndex = ++ itemsInserted% QUEUE_CAPACITY; circularQueue [writeIndex] = værdi; }}
Brug af modulo-operatoren forhindrer vi skrivIndex at falde ud af grænserne for arrayet, derfor får vi aldrig et ArrayIndexOutOfBoundsException.
Men når vi først indsætter mere end QUEUE_CAPACITY varer, vil det næste element overskrive det første.
4. Konklusion
Moduloperatoren bruges til at beregne resten af et heltal, der ellers mistede.
Det er nyttigt at gøre enkle ting som at finde ud af, om et givet tal er lige eller ulige, samt mere komplekse opgaver som at spore den næste skriveposition i et cirkulært array.
Eksempelkoden er tilgængelig i GitHub-arkivet.