Recherche de la valeur max / min dans un tableau de primitives à l'aide de Java

192

Il est trivial d'écrire une fonction pour déterminer la valeur min / max dans un tableau, telle que:

/**
 * 
 * @param chars
 * @return the max value in the array of chars
 */
private static int maxValue(char[] chars) {
    int max = chars[0];
    for (int ktr = 0; ktr < chars.length; ktr++) {
        if (chars[ktr] > max) {
            max = chars[ktr];
        }
    }
    return max;
}

mais n'est-ce pas déjà fait quelque part?

Nick Heiner
la source
8
Un tableau de primitive à un tableau de conteneurs aiderait: stackoverflow.com/questions/3770289/... suivi de Collections.max(Arrays.asList()).
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
J'adore la stupidité de Java
Farid le

Réponses:

174

Utilisation de Commons Lang (pour convertir) + Collections (en min / max)

import java.util.Arrays;
import java.util.Collections;

import org.apache.commons.lang.ArrayUtils;

public class MinMaxValue {

    public static void main(String[] args) {
        char[] a = {'3', '5', '1', '4', '2'};

        List b = Arrays.asList(ArrayUtils.toObject(a));

        System.out.println(Collections.min(b));
        System.out.println(Collections.max(b));
   }
}

Notez que cela Arrays.asList()enveloppe le tableau sous-jacent, il ne doit donc pas être trop gourmand en mémoire et il ne doit pas effectuer de copie sur les éléments du tableau.

Michael Rutherfurd
la source
9
qu'est-ce que c'estArrayUtils
Basheer AL-MOMANI
4
Arrays.asList()devrait être bien, mais ArrayUtils.toObject()copiera chaque élément de adans un nouveau tableau de Character.
EM
5
Arrays.asList(a)ne fonctionne pas. Vous ne pouvez pas faire une liste de primitives ( List<char>dans ce cas). Vous devez d'abord convertir les valeurs primitives en objets et c'est pourquoi il ArrayUtils.toObjectest utilisé.
nessa.gp
108

Vous pouvez simplement utiliser les nouvelles Java 8 Streams , mais vous devez travailler avec int.

La streamméthode de la classe utilitaire Arraysvous donne un IntStreamsur lequel vous pouvez utiliser la minméthode. Vous pouvez aussi le faire max, sum, average, ...

La getAsIntméthode est utilisée pour obtenir la valeur duOptionalInt

import java.util.Arrays;

public class Test {
    public static void main(String[] args){
        int[] tab = {12, 1, 21, 8};
        int min = Arrays.stream(tab).min().getAsInt();
        int max = Arrays.stream(tab).max().getAsInt();
        System.out.println("Min = " + min);
        System.out.println("Max = " + max)
    }

}

== MISE À JOUR ==

Si le temps d'exécution est important et que vous souhaitez parcourir les données une seule fois, vous pouvez utiliser la summaryStatistics()méthode comme celle-ci

import java.util.Arrays;
import java.util.IntSummaryStatistics;

public class SOTest {
    public static void main(String[] args){
        int[] tab = {12, 1, 21, 8};
        IntSummaryStatistics stat = Arrays.stream(tab).summaryStatistics();
        int min = stat.getMin();
        int max = stat.getMax();
        System.out.println("Min = " + min);
        System.out.println("Max = " + max);
    }
}

Cette approche peut donner de meilleures performances que la boucle classique car la summaryStatisticsméthode est une opération de réduction et elle permet la parallélisation.

Ortomala Lokni
la source
59

La bibliothèque Google Guava a des méthodes min et max dans ses classes Chars, Ints, Longs, etc.

Vous pouvez donc simplement utiliser:

Chars.min(myarray)

Aucune conversion n'est requise et probablement mise en œuvre efficacement.

Andrew McKinlay
la source
4
Il est implémenté plus ou moins comme dans la question sauf qu'il lance une exception IllegalArgumentException pour un tableau de longueur 0. ( code.google.com/p/guava-libraries/source/browse/trunk/src/com/… )
ColinD
3
C'est la meilleure solution de tout ici. Évite toute cette confusion java.util.Arrays # asList varargs.
Kong
20

Oui, c'est fait dans la classe Collections . Notez que vous devrez convertir manuellement votre tableau de caractères primitifs en Character [].

Une courte démo:

import java.util.*;

public class Main {

    public static Character[] convert(char[] chars) {
        Character[] copy = new Character[chars.length];
        for(int i = 0; i < copy.length; i++) {
            copy[i] = Character.valueOf(chars[i]);
        }
        return copy;
    }

    public static void main(String[] args) {
        char[] a = {'3', '5', '1', '4', '2'};
        Character[] b = convert(a);
        System.out.println(Collections.max(Arrays.asList(b)));
    }
}
Bart Kiers
la source
1
Collections.min (maCollection); Si vous souhaitez l'utiliser pour les tableaux, vous pouvez le faire comme Collections.min (Arrays.asList (myArray));
Zed du
3
la conversion de a char []en a Character []uniquement pour déterminer le maximum est assez inefficace - mieux vaut créer une classe utilitaire avec des méthodes statiques pour chaque type de primitif similaire à java.util.Arrays: java.sun.com/javase/6/docs/api/java/util/Arrays.html
Christoph
@Christoph: oui, si la taille du tableau est grande, je serais d'accord. Le simple fait de dire qu'il est "inefficace" n'a pas de sens si l'application en question effectue de nombreux appels de base de données et / ou opérations d'E / S et que la taille du tableau est (relative) petite.
Bart Kiers
vous devriez utiliser à la Character.valueOf(chars[i])place de new Character(chars[i])pour des raisons de performances: java.sun.com/javase/6/docs/api/java/lang/…
Christoph
@Christoph Christoph a raison, il est inefficace et stupide de transformer un tableau en Collection, pour une recherche min max.
AlexWien
15
import java.util.Arrays;

public class apples {

  public static void main(String[] args) {
    int a[] = {2,5,3,7,8};
    Arrays.sort(a);

     int min =a[0];
    System.out.println(min);
    int max= a[a.length-1];
    System.out.println(max);

  }

}
Lubna_Nsour
la source
4
Veuillez fournir quelques explications.
Mike Stockdale
3
Je pense que cela signifie que si vous triez le tableau (par ordre croissant), par définition, la valeur minimale sera toujours à la première position, un [0], et la valeur maximale sera toujours à la dernière position , [a.longueur-1].
Jeff
1
C'est une manière légitime et utile de résoudre le problème. Quel est l'inconvénient de l'utiliser par rapport aux autres?
Alex
8
@alex time complexité - le tri est au mieux une affaire O (nlogn), tandis que l'approche de Michael Rutherfurd est O (n).
jajdoo
4
Nous n'avons pas besoin de tri car une seule itération sur la liste suffit pour trouver le min et le max.
akhil_mittal
11

J'ai une petite classe d'aide dans toutes mes applications avec des méthodes comme:

public static double arrayMax(double[] arr) {
    double max = Double.NEGATIVE_INFINITY;

    for(double cur: arr)
        max = Math.max(max, cur);

    return max;
}
Sauer
la source
1
Vous devez utiliser double max = Double.NEGATIVE_INFINITY; au lieu de double max = Double.MIN_VALUE; Comme MIN_VALUE pour le double est positif
krems
1
... ou vous pouvez définir max sur le premier élément du tableau et itérer à partir du 2ème élément, voir ma réponse.
Nicholas Hamilton
3

Vous pouvez facilement le faire avec un IntStreamet la max()méthode.

Exemple

public static int maxValue(final int[] intArray) {
  return IntStream.range(0, intArray.length).map(i -> intArray[i]).max().getAsInt();
}

Explication

  1. range(0, intArray.length)- Pour obtenir un flux avec autant d'éléments que ceux présents dans le intArray.

  2. map(i -> intArray[i])- Mappez chaque élément du flux à un élément réel du intArray.

  3. max()- Obtenez l'élément maximum de ce flux sous forme de OptionalInt.

  4. getAsInt()- Déballez le fichier OptionalInt. (Vous pouvez également utiliser ici:, orElse(0)juste au cas où le OptionalIntserait vide.)

winklerrr
la source
2
import java.util.Random;

public class Main {

public static void main(String[] args) {
   int a[] = new int [100];
   Random rnd = new Random ();

    for (int i = 0; i< a.length; i++) {
        a[i] = rnd.nextInt(99-0)+0;
        System.out.println(a[i]);
    }

    int max = 0;          

    for (int i = 0; i < a.length; i++) {
        a[i] = max;


        for (int j = i+1; j<a.length; j++) {
            if (a[j] > max) {
               max = a[j];
            }

        }
    }

    System.out.println("Max element: " + max);
}
}
Marque 2
la source
2
    public int getMin(int[] values){
        int ret = values[0];
        for(int i = 1; i < values.length; i++)
            ret = Math.min(ret,values[i]);
        return ret;
    }
Nicholas Hamilton
la source
Ceci est pour les nombres intmais la question demande des valeurs primitivesint, long, char, byte....
IgniteCoders
2

Une solution avec reduce():

int[] array = {23, 3, 56, 97, 42};
// directly print out
Arrays.stream(array).reduce((x, y) -> x > y ? x : y).ifPresent(System.out::println);

// get the result as an int
int res = Arrays.stream(array).reduce((x, y) -> x > y ? x : y).getAsInt();
System.out.println(res);
>>
97
97

Dans le code ci-dessus, reduce()renvoie les données au Optionalformat, que vous pouvez convertir inten getAsInt().

Si nous voulons comparer la valeur maximale avec un certain nombre, nous pouvons définir une valeur de départ dans reduce():

int[] array = {23, 3, 56, 97, 42};
// e.g., compare with 100
int max = Arrays.stream(array).reduce(100, (x, y) -> x > y ? x : y);
System.out.println(max);
>>
100

Dans le code ci-dessus, lorsqu'il a reduce()une identité (valeur de départ) comme premier paramètre, il renvoie des données dans le même format avec l'identité. Avec cette propriété, nous pouvons appliquer cette solution à d'autres tableaux:

double[] array = {23.1, 3, 56.6, 97, 42};
double max = Arrays.stream(array).reduce(array[0], (x, y) -> x > y ? x : y);
System.out.println(max);
>>
97.0
Simon Z.
la source
2

Voici une classe utilitaire fournissant des min/maxméthodes pour les types primitifs: Primitives.java

int [] numbers= {10,1,8,7,6,5,2};
    int a=Integer.MAX_VALUE;
    for(int c:numbers) {
        a=c<a?c:a;
        }
        
    System.out.println("Lowest value is"+a);
Christoph
la source
1

Exemple avec float:

public static float getMaxFloat(float[] data) {

    float[] copy = Arrays.copyOf(data, data.length);
    Arrays.sort(copy);
    return copy[data.length - 1];
}

public static float getMinFloat(float[] data) {

    float[] copy = Arrays.copyOf(data, data.length);
    Arrays.sort(copy);
    return copy[0];
}
Andrew
la source
Bien que votre solution fonctionnera, mais elle augmentera la complexité de temps à O (nlogn) tandis que min peut être trouvé facilement dans O (n) en utilisant d'autres réponses.
Pramod
tout simplement fou d'utiliser un tri dans cette situation.
Nicholas Hamilton
Cela peut être utile lorsque la première valeur n> 1 la plus petite / la plus grande est nécessaire, avec quelques réparations.
biziclop
1

Voici une solution pour obtenir la valeur maximale dans environ 99% des exécutions (modifiez la valeur 0,01 pour obtenir un meilleur résultat):

public static double getMax(double[] vals){
    final double[] max = {Double.NEGATIVE_INFINITY};

    IntStream.of(new Random().ints((int) Math.ceil(Math.log(0.01) / Math.log(1.0 - (1.0/vals.length))),0,vals.length).toArray())
            .forEach(r -> max[0] = (max[0] < vals[r])? vals[r]: max[0]);

    return max[0];
}

(Pas complètement sérieux)

mnzl
la source
;-) C'est "pas complètement sérieux" d'accord. Hésitant à voter pour…
Ole VV
0

Passez le tableau à une méthode qui le trie Arrays.sort()afin qu'elle ne trie que le tableau que la méthode utilise, puis définit min à array[0]et max à array[array.length-1].

whoduexpect
la source
3
Il est probablement intéressant de noter que a) cela modifie le tableau, et b) pour les grands tableaux, c'est une solution plus chère O (nlog n) plutôt que O (n)
davidsheld
0

La méthode de base pour obtenir la valeur min / max d'un tableau. Si vous avez besoin du tableau non trié, vous pouvez créer une copie ou la transmettre à une méthode qui renvoie le min ou le max. Sinon, le tableau trié est meilleur car il fonctionne plus rapidement dans certains cas.

public class MinMaxValueOfArray {
    public static void main(String[] args) {
        int[] A = {2, 4, 3, 5, 5};
        Arrays.sort(A);
        int min = A[0];
        int max = A[A.length -1];
        System.out.println("Min Value = " + min);        
        System.out.println("Max Value = " + max);
    }
}
Kim G.
la source
2
Le problème avec le tri est qu'il a une surcharge O (n log n) pour un problème O (n). Mais c'est mieux que les trois autres réponses «trier le tableau» déjà données.
Teepeemm