Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.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
Java8流中的argmax?_Java_Java 8_Java Stream_Argmax - Fatal编程技术网

Java8流中的argmax?

Java8流中的argmax?,java,java-8,java-stream,argmax,Java,Java 8,Java Stream,Argmax,我经常需要集合的最大元素,根据产生双精度或int值的条件的最大化。Streams有max()函数,它需要我实现一个比较器,我觉得这很麻烦。下面的示例中是否有更简洁的语法,例如names.stream().argmax(String::length) import java.util.Arrays; import java.util.Comparator; import java.util.List; public class ArgMax { public static void ma

我经常需要集合的最大元素,根据产生双精度或int值的条件的最大化。Streams有max()函数,它需要我实现一个比较器,我觉得这很麻烦。下面的示例中是否有更简洁的语法,例如
names.stream().argmax(String::length)

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

public class ArgMax
{
    public static void main(String[] args)
    {
        List<String> names = Arrays.asList("John","Joe","Marilyn");
        String longestName = names.stream().max((String s,String t)->(Integer.compare(s.length(),t.length()))).get();
        System.out.println(longestName);
    }
}
导入java.util.array;
导入java.util.Comparator;
导入java.util.List;
公共类ArgMax
{
公共静态void main(字符串[]args)
{
List name=Arrays.asList(“John”、“Joe”、“Marilyn”);
String longestName=names.stream().max((字符串s,字符串t)->(Integer.compare(s.length(),t.length())).get();
System.out.println(longestName);
}
}
使用

比较某些属性上的元素(可能比这更复杂,但不必如此)


,如果
可能为空,那么像这样使用
可选的#get()
是不安全的。你最好使用一种更安全的检索方法,比如如果没有max ./p>< p>它会给你一些缺省值。我认为应该考虑到<>代码> max /<代码> min >代码>是唯一的,这当然不是<代码> > ARGMAX <代码> />代码> ARMIN < /代码>的保证;这尤其意味着减少的类型应该是一个集合,例如
列表
。这需要比上面建议的更多的工作

下面的
ArgMaxCollector
类提供了这种简化的简单实现。
main
显示此类的应用程序,用于计算字符串集的
argMax
/
argMin

one two three four five six seven
按长度排序。输出(分别报告
argMax
argMin
采集器的结果)应为

[three, seven]
[one, two, six]
分别是两个最长的字符串和三个最短的字符串

这是我第一次尝试使用新的Java8流API,所以任何评论都是非常受欢迎的

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collector;

class ArgMaxCollector<T> {

    private T max = null;
    private ArrayList<T> argMax = new ArrayList<T>();
    private Comparator<? super T> comparator;

    private ArgMaxCollector( Comparator<? super T> comparator ) {
        this.comparator = comparator;
    }

    public void accept( T element ) {
        int cmp = max == null ? -1 : comparator.compare( max, element );
        if ( cmp < 0 ) {
            max = element;
            argMax.clear();
            argMax.add( element );
        } else if ( cmp == 0 )
            argMax.add( element );
    }

    public void combine( ArgMaxCollector<T> other ) {
        int cmp = comparator.compare( max, other.max );
        if ( cmp < 0 ) {
            max = other.max;
            argMax = other.argMax;
        } else if ( cmp == 0 ) {
            argMax.addAll( other.argMax );
        }
    }

    public List<T> get() {
        return argMax;
    }

    public static <T> Collector<T, ArgMaxCollector<T>, List<T>> collector( Comparator<? super T> comparator ) {
        return Collector.of(
            () -> new ArgMaxCollector<T>( comparator ),
            ( a, b ) -> a.accept( b ),
            ( a, b ) ->{ a.combine(b); return a; },
            a -> a.get() 
        );
    }
}

public class ArgMax {

    public static void main( String[] args ) {

        List<String> names = Arrays.asList( new String[] { "one", "two", "three", "four", "five", "six", "seven" } );

        Collector<String, ArgMaxCollector<String>, List<String>> argMax = ArgMaxCollector.collector( Comparator.comparing( String::length ) );
        Collector<String, ArgMaxCollector<String>, List<String>> argMin = ArgMaxCollector.collector( Comparator.comparing( String::length ).reversed() );

        System.out.println( names.stream().collect( argMax ) );
        System.out.println( names.stream().collect( argMin ) );

    }

}
import java.util.ArrayList;
导入java.util.array;
导入java.util.Comparator;
导入java.util.List;
导入java.util.stream.Collector;
类ArgMaxCollector{
私有T max=null;
private ArrayList argMax=new ArrayList();

private Comparator这里的简单高效解决方案:

/**返回argmin项,如果没有,则返回null。跳过NAN分数*/
公共静态T argmin(流,ToDoubleFunction记分器){
双最小值=零;
T argmin=null;
for(tp:(Iterable)stream::iterator){
双倍得分=记分员。双(p);
如果(最小==null | |最小>分数){
最小值=分数;
argmin=p;
}
}
返回argmin;
}

Gah!不要在最后使用raw
get()
,否则如果流是空的,你会抛出NSEE。使用安全的方法,比如
orElse
orelsetrow
,或者
ifPresent
@BrianGoetz我想我们已经发现了Brian的一个过敏症状。每当我写
Optional.get()
也是。@StuartMarks确实如此。我们不应该叫它
get
。我们应该叫它
getOrThrow()
orelsetrow()
getUnsafely()
或者可能只是
getorthrownosuchelementExceptionofthis optionalisnotpresent())
。在这种情况下,如何获取longestName值的索引?我假设
names.indexOf(longestName)
是可以的?@zygimantus:如果你可以接受第二次线性搜索,那么可以。否则,使用
IntStream.range(0,names.length()).boxed().max(Comparator.comparingit(ix->names.get().length())
首先搜索索引。
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collector;

class ArgMaxCollector<T> {

    private T max = null;
    private ArrayList<T> argMax = new ArrayList<T>();
    private Comparator<? super T> comparator;

    private ArgMaxCollector( Comparator<? super T> comparator ) {
        this.comparator = comparator;
    }

    public void accept( T element ) {
        int cmp = max == null ? -1 : comparator.compare( max, element );
        if ( cmp < 0 ) {
            max = element;
            argMax.clear();
            argMax.add( element );
        } else if ( cmp == 0 )
            argMax.add( element );
    }

    public void combine( ArgMaxCollector<T> other ) {
        int cmp = comparator.compare( max, other.max );
        if ( cmp < 0 ) {
            max = other.max;
            argMax = other.argMax;
        } else if ( cmp == 0 ) {
            argMax.addAll( other.argMax );
        }
    }

    public List<T> get() {
        return argMax;
    }

    public static <T> Collector<T, ArgMaxCollector<T>, List<T>> collector( Comparator<? super T> comparator ) {
        return Collector.of(
            () -> new ArgMaxCollector<T>( comparator ),
            ( a, b ) -> a.accept( b ),
            ( a, b ) ->{ a.combine(b); return a; },
            a -> a.get() 
        );
    }
}

public class ArgMax {

    public static void main( String[] args ) {

        List<String> names = Arrays.asList( new String[] { "one", "two", "three", "four", "five", "six", "seven" } );

        Collector<String, ArgMaxCollector<String>, List<String>> argMax = ArgMaxCollector.collector( Comparator.comparing( String::length ) );
        Collector<String, ArgMaxCollector<String>, List<String>> argMin = ArgMaxCollector.collector( Comparator.comparing( String::length ).reversed() );

        System.out.println( names.stream().collect( argMax ) );
        System.out.println( names.stream().collect( argMin ) );

    }

}
/** return argmin item, else null if none.  NAN scores are skipped */
public static <T> T argmin(Stream<T> stream, ToDoubleFunction<T> scorer) {
    Double min = null;
    T argmin = null;
    for (T p: (Iterable<T>) stream::iterator) {
        double score = scorer.applyAsDouble(p);
        if (min==null || min > score) {
            min = score;
            argmin = p;
        }
    }
    return argmin;
}