Modulo-operatøren i Java
1. Oversikt
I denne korte opplæringen skal vi vise hva modulooperatøren er, og hvordan vi kan bruke den med Java for noen vanlige brukssaker.
2. Modulo-operatøren
La oss starte med manglene ved enkel deling i Java.
Hvis operandene på begge sider av divisjonsoperatøren har type int, resultatet av operasjonen er et annet int:
@Test offentlig ugyldig nårIntegerDivision_thenLosesRemainder () {assertThat (11/4) .isEqualTo (2); }
Den samme divisjonen gir oss et annet resultat når minst en av operandene har type flyte eller dobbelt:
@Test offentlig ugyldig nårDoubleDivision_thenKeepsRemainder () {assertThat (11 / 4.0) .isEqualTo (2.75); }
Vi kan se at vi mister resten av en divisjonsoperasjon når vi deler heltall.
Moduloperatøren gir oss nøyaktig denne resten:
@Test offentlig ugyldig nårModulo_thenReturnsRemainder () {assertThat (11% 4) .isEqualTo (3); }
Resten er det som gjenstår etter å ha delt 11 (utbyttet) med 4 (deleren) - i dette tilfellet 3.
Av samme grunn er det ikke mulig å dele med null, og det er ikke mulig å bruke modulo-operatøren når argumentet til høyre er null.
Både delingen og moduloperasjonen kaster en Aritmetisk unntak når vi prøver å bruke null som operand på høyre side:
@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. Vanlige brukstilfeller
Det vanligste bruksområdet for modulo-operatøren er å finne ut om et gitt tall er oddetall eller jevnt.
Hvis utfallet av moduloperasjonen mellom et tall og to er lik ett, er det et oddetall:
@Test offentlig ugyldig nårDivisorIsOddAndModulusIs2_thenResultIs1 () {assertThat (3% 2) .isEqualTo (1); }
På den annen side, hvis resultatet er null (dvs. det er ingen rest), er det et partall:
@Test offentlig ugyldig nårDivisorIsEvenAndModulusIs2_thenResultIs0 () {assertThat (4% 2) .isEqualTo (0); }
En annen god bruk av moduloperasjonen er å holde oversikt over indeksen til neste ledige punkt i en sirkulær matrise.
I en enkel implementering av en sirkulær kø for int verdier, holdes elementene i en matrise med fast størrelse.
Hver gang vi vil skyve et element til den sirkulære køen vår, beregner vi bare neste ledige posisjon ved å beregne modulo for antall elementer vi allerede har satt inn pluss 1 og køkapasiteten:
@Test offentlig ugyldig nårItemsIsAddedToCircularQueue_thenNoArrayIndexOutOfBounds () {int QUEUE_CAPACITY = 10; int [] circularQueue = ny int [QUEUE_CAPACITY]; int itemsInserted = 0; for (int verdi = 0; verdi <1000; verdi ++) {int writeIndex = ++ itemsInserted% QUEUE_CAPACITY; circularQueue [writeIndex] = verdi; }}
Ved å bruke modulo-operatøren forhindrer vi writeIndex for å falle ut av grensen til matrisen, får vi derfor aldri en ArrayIndexOutOfBoundsException.
Imidlertid, når vi setter inn mer enn QUEUE_CAPACITY elementer, vil neste element overskrive det første.
4. Konklusjon
Moduloperatøren brukes til å beregne resten av en heltallsdeling som ellers mistet.
Det er nyttig å gjøre enkle ting som å finne ut om et gitt tall er jevnt eller merkelig, samt mer komplekse oppgaver som å spore neste skriveposisjon i et sirkulært utvalg.
Eksempelkoden er tilgjengelig i GitHub-depotet.