Javaを使用してプリミティブの配列の最大/最小値を見つける


185

次のような配列の最小値/最大値を決定する関数を書くのは簡単です。

/**
 * 
 * @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;
}

しかし、これはすでにどこかで行われていませんか?


8
プリミティブの配列からコンテナーの配列への変換は、stackoverflow.com / questions / 3770289 / …の後に役立ちますCollections.max(Arrays.asList())
Ciro Santilli郝海东冠状病六四事件法轮功

私はJavaがいかに馬鹿であるかが大好きです
Farid

回答:


173

Commons Lang(変換)+コレクション(最小/最大)の使用

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));
   }
}

Arrays.asList()基になる配列をラップすることに注意してください。そのため、メモリを大量に消費しないようにし、配列の要素に対してコピーを実行しないでください。


9
ArrayUtils
ですか

4
Arrays.asList()は問題ありませんが、のArrayUtils.toObject()各要素aをの新しい配列にコピーしますCharacter
EM

5
Arrays.asList(a)動作しません。プリミティブのリストを作成することはできません(List<char>この場合)。最初に、プリミティブ値をオブジェクトに変換する必要がありますArrayUtils.toObject。そのため、が使用されます。
nessa.gp 2017

96

あなたは、単に新しいJava 8を使用することができますStreamしかし、あなたが仕事をしなければなりませんint

streamユーティリティクラスのメソッドは、メソッドを使用できる場所をArrays提供します。あなたも行うことができます、、、...IntStreamminmaxsumaverage

このgetAsIntメソッドは、OptionalInt

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)
    }

}

==更新==

実行時間が重要で、summaryStatistics()このようなメソッドを使用できるのは1回だけデータを調べたい場合

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);
    }
}

このsummaryStatistics方法は縮小演算であり、並列化が可能であるため、このアプローチは従来のループよりも優れたパフォーマンスを提供できます。


57

Googleのグアバライブラリは、その文字数など、int型、ロングス、クラスで最小と最大のメソッドがあります。

だからあなたは単に使うことができます:

Chars.min(myarray)

変換は不要で、おそらく効率的に実装されています。


4
それは長さ0の配列に対してIllegalArgumentExceptionをスローすることを除いて、多かれ少なかれ質問のように実装されています。(code.google.com/p/guava-libraries/source/browse/trunk/src/com/…
ColinD

3
これは、ここでのすべての最良のソリューションです。java.util.Arrays#asList varargsの混乱をすべて回避します。
コング

20

はい、Collectionsクラスで行われます。プリミティブchar配列を手動でCharacter []に変換する必要があることに注意してください。

短いデモ:

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)));
    }
}

1
Collections.min(myCollection); 配列に使用する場合は、Collections.min(Arrays.asList(myArray));のように使用できます。
Zed

3
a char []をに変換してCharacter []最大値を決定することは非常に非効率的java.util.Arraysです。java.sun.com
クリストフ

@Christoph:はい、配列のサイズが大きい場合は同意します。問題のアプリケーションが多くのデータベース呼び出しやI / O操作を行い、配列のサイズが(相対的に)小さい場合、単に「非効率的」であると述べるだけでは意味がありません。
Bart Kiers、2009

パフォーマンス上の理由からCharacter.valueOf(chars[i])、代わりにjava.sun.com/javase/6/docs/api/java/lang/…new Character(chars[i])を使用する必要があります
Christoph

@Christoph Christophは正解です。配列をコレクションに変換して最小検索を行うのは非効率的で愚かです。
AlexWien 2013

16
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);

  }

}

4
説明してください。
Mike Stockdale 2014

3
これが言うことの意味は、配列を(昇順で)ソートすると、定義により、最小値は常に最初の位置、a [0]になり、最大値は常に最後の位置になるということです。 、[a.length-1]。
ジェフ

1
これは、問題を解決するための正当で有用な方法です。他のものと比較してそれを使用することの欠点は何ですか?
Alex

8
@alex時間の複雑さ-並べ替えはせいぜいO(nlogn)の問題ですが、Michael RutherfurdのアプローチはO(n)です。
jajdoo 2015年

3
リストに対する単一の反復で最小値と最大値を見つけるのに十分であるため、ソートは必要ありません。
akhil_mittal 2015

11

すべてのアプリケーションに、次のようなメソッドを持つ小さなヘルパークラスがあります。

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

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

    return max;
}

1
double max = Double.NEGATIVE_INFINITY;を使用する必要があります。double max = Double.MIN_VALUE;の代わりに doubleのMIN_VALUEが正な
ので

1
...または、配列の最初の項目にmaxを設定し、2番目の項目から繰り返すことができます。私の答えを参照してください。
ニコラスハミルトン

3

IntStreammax()メソッドを使用して簡単に行うことができます。

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

説明

  1. range(0, intArray.length)-にある要素と同じ数の要素を含むストリームを取得するintArray

  2. map(i -> intArray[i])-ストリームのすべての要素をの実際の要素にマッピングしintArrayます。

  3. max()-このストリームの最大要素をとして取得しOptionalIntます。

  4. getAsInt()-を展開しOptionalIntます。(が空のorElse(0)場合に備えて、ここでも使用できOptionalIntます。)



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);
}
}

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;
    }

これは数値用ですintが、問題はプリミティブ値を要求することですint, long, char, byte....
IgniteCoders 2018年

2

ソリューション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

上記のコードでは、reduce()内のデータを返しOptionalますが、に変換できる形式、intでをgetAsInt()

最大値を特定の数値と比較する場合は、次のように開始値を設定できます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

上記のコードでreduce()、最初のパラメーターとしてID(開始値)を使用すると、IDと同じ形式でデータが返されます。このプロパティを使用すると、このソリューションを他のアレイに適用できます。

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

1

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];
}

ソリューションは機能しますが、O(nlogn)への時間の複雑さが増しますが、他の回答を使用することでO(n)でminを簡単に見つけることができます。
Pramod 2018

この状況で一種のソートを使用するのはおかしいだけです。
ニコラスハミルトン

最初のn> 1の最小値/最大値が必要な場合、いくつかの修復が必要な場合に役立ちます。
biziclop

1

これは、実行の約99%で最大値を取得するための解決策です(より良い結果を得るために0.01を変更します)。

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];
}

(完全に深刻ではない)


;-)それは「完全に深刻ではない」です。賛成投票をためらう
Ole VV 2018

0

並べ替え、それをそのメソッドに配列を渡すArrays.sort()ことが唯一の方法が使用している配列をソートして、次にセットarray[0]して最大をしますarray[array.length-1]


3
a)これは配列を変更し、b)大きな配列の場合、O(n)よりもO(nlog n)の方が高価なソリューションであることに注意してください
davidsheldon

0

配列の最小値/最大値を取得する基本的な方法。ソートされていない配列が必要な場合は、コピーを作成するか、それを最小値または最大値を返すメソッドに渡すことができます。そうでない場合、並べ替えられた配列は、場合によってはより高速に実行されるため、より優れています。

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);
    }
}

2
ソートの問題は、O(n)の問題に対してO(n log n)のオーバーヘッドがあることです。しかし、これはすでに与えられた他の3つの「配列のソート」の回答よりも優れています。
Teepeemm 2015年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.