Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 从数组中查找第二个最小元素_Java_Arrays_Lambda_Java 8_Java Stream - Fatal编程技术网

Java 从数组中查找第二个最小元素

Java 从数组中查找第二个最小元素,java,arrays,lambda,java-8,java-stream,Java,Arrays,Lambda,Java 8,Java Stream,任何人都可以将其转换为Java函数样式(lambda): public int findsecodmin(int arr[]{ int min=Integer.MAX\u值,secondMin=Integer.MAX\u值; 对于(int i=0;iarr[i]){ 第二分钟=分钟; 最小值=arr[i]; }否则如果(第二分钟>到达时间[i]){ secondMin=arr[i]; } } 返回第二分钟; } 我尝试将过滤器应用于此,但它不起作用。使用IntStream,您可以轻松对其进行排

任何人都可以将其转换为Java函数样式(lambda):

public int findsecodmin(int arr[]{
int min=Integer.MAX\u值,secondMin=Integer.MAX\u值;
对于(int i=0;iarr[i]){
第二分钟=分钟;
最小值=arr[i];
}否则如果(第二分钟>到达时间[i]){
secondMin=arr[i];
}
}
返回第二分钟;
}

我尝试将过滤器应用于此,但它不起作用。

使用
IntStream
,您可以轻松对其进行排序并跳过第一个元素:

public int findSecondMin(int[] arr)
{
    return IntStream.of(arr).sorted().skip(1).findFirst().orElse(Integer.MAX_VALUE);
}
SortedSet<Integer> sortedSet = Arrays.stream(arr)
                                     .boxed()
                                     .collect(Collectors
                                         .toCollection(TreeSet::new));
sortedSet.remove(sortedSet.first());
int secondMin = sortedSet.first();

System.out.println(secondMin); // prints 3
但当然,您不必使用流
java.util.Arrays
有一个很好的排序方法,然后您只需使用第二个元素:

public int findSecondMin(int[] arr)
{
    Arrays.sort(arr);
    return arr.length < 2 ? Integer.MAX_VALUE : arr[1];
}
public int findsecodmin(int[]arr)
{
数组。排序(arr);
返回arr.length<2?Integer.MAX_值:arr[1];
}
为了避免对整个阵列进行排序,我们可以采用您的方法,并将其调整为流上的自定义缩减:

public int findSecondMin(int[] arr)
{
    return IntStream.of(arr).boxed().reduce(
        new int[] {Integer.MAX_VALUE, Integer.MAX_VALUE},
        (mins, i) -> {
            return new int[] {Math.min(i, mins[0]), Math.min(Math.max(i, mins[0]), mins[1])};
        }, (mins1, mins2) -> {
            int[] lesser = mins1[0] < mins2[0] ? mins1 : mins2;
            int[] larger = mins1[0] < mins2[0] ? mins2 : mins1;
            return new int[] {lesser[0], Math.min(lesser[1], larger[0])};
        }
    )[1];
}
public int findsecodmin(int[]arr)
{
返回IntStream.of(arr.boxed().reduce(
新int[]{Integer.MAX_值,Integer.MAX_值},
(一分钟)->{
返回新的int[]{Math.min(i,min[0]),Math.min(Math.max(i,min[0]),min[1]);
},(第1分钟、第2分钟)->{
int[]lesser=mins1[0]

与基于for循环的实现相比,它可能更难阅读,但可以并行工作。

这里是示例

    List<Integer> numbers = Arrays.asList(10, 2, 3, 4, 5, 6);
            numbers.sort(Comparator.naturalOrder());
            System.out.println(numbers.get(1));
List number=Arrays.asList(10,2,3,4,5,6);
numbers.sort(Comparator.naturalOrder());
System.out.println(number.get(1));

在所有数字都是唯一的情况下,即使不进行排序也有一种方法。过滤掉最小值,然后再次请求另一个值,得到第二个最小值

int firstMin = Arrays.stream(arr).min().getAsInt();
int secondMin = Arrays.stream(arr).filter(i -> i != firstMin).min().getAsInt();

System.out.println(firstMin);  // prints 2
System.out.println(secondMin); // prints 3

编辑:还有另一种方法使用
TreeSet
实现,它存储已排序的值。移除最低的元素并再次请求第一个元素-结果是第二个最低元素:

public int findSecondMin(int[] arr)
{
    return IntStream.of(arr).sorted().skip(1).findFirst().orElse(Integer.MAX_VALUE);
}
SortedSet<Integer> sortedSet = Arrays.stream(arr)
                                     .boxed()
                                     .collect(Collectors
                                         .toCollection(TreeSet::new));
sortedSet.remove(sortedSet.first());
int secondMin = sortedSet.first();

System.out.println(secondMin); // prints 3
SortedSet-SortedSet=Arrays.stream(arr)
.boxed()
.收藏(收藏家)
.toCollection(TreeSet::new));
sortedSet.remove(sortedSet.first());
int secondMin=sortedSet.first();
系统输出打印项次(秒分钟);//印刷品3
编辑: 正如在评论中提到的-下面的解决方案将不适用于并行处理

为了避免排序,我们可以使用
reduce
函数。并简化为“成对结构”(在array模仿的示例中):

公共类测试{
私有静态final int SECOND_lower=1;
私有静态最终整数最低=0;
@试验
公开无效测试(){
整数[]arr={0,3,4,5,2,3,5,6,7,8,1};
List=Arrays.asList(arr);
int[]标识={Integer.MAX_值,Integer.MAX_值};
int[]result=list.stream()
.减少(标识,(acc,elem)->计算(acc,elem),(acc1,acc2)->acc1;
System.out.println(Arrays.toString(result));
}
私有int[]计算(int[]acc,整数元素){
如果(附件[最低]>要素){
int PREVSLOWEST=acc[最低];
acc[最低]=元素;
acc[第二低]=上一低;
}否则如果(acc[第二低]>elem){
acc[第二低]=元素;
}
返回acc;
}
public int min(){
int a[]={2,5,1,3};
int min,secondMin=a[0];
对于(int i=0;ia[i]){
第二分钟=分钟;
min=a[i];
}
}
返回第二分钟;
}

我从上面的代码段中得到了第二分钟…试试这个…

如果对数组进行排序,它将变成O(nlogn)。是的,这是一个缺点。但是,我真的不明白基于流的解决方案如何在不依赖外部状态的情况下实现目标,或者不完全像原始for循环那样使用自定义reduce对象。这些基于排序的解决方案至少可读性很强。@Malte Hartwig您能解释一下时间复杂性吗,因为根据我的说法,排序是o(n^2)?@SandeepTiwari复杂性取决于选择的排序算法。像冒泡排序这样的基本方法确实倾向于n2,但是Java函数将依赖于更高级的技术。来自
Arrays.sort()的JavaDoc:“实现说明:排序算法是一种双枢轴快速排序”。您可以检查JavaDoc中的流排序,然后检查那些算法。
(acc1,acc2)->acc1
。。。只需添加
parallel
,然后查看您将得到的结果。我没有想到并行化。但是您是对的,完整的解决方案应该考虑到这一点。因为您正在修改临时数组,所以应该使用
collect
,它是专门为处理所谓的可变缩减而设计的。
public int min(){
  int a[] ={2,5,1,3};
  int min, secondMin = a[0];
  for(int i=0;i<a.length;i++){
        if(min>a[i]){
             secondMin =min;
             min= a[i];
           }
      }
  return secondMin;
}