如何获得给定阵列列表的最大国家/地区

时间:2018-11-25 04:32:38

标签: java collections java-8 java-stream comparator

如何获取结果集为{GERMANY = 3}而不是{GERMANY = 3,POLAND = 2,UK = 3}

import numpy as np
import tensorflow as tf
from keras.layers import Input, Dense, Flatten
from keras.models import Model
import keras.backend as K
from keras.engine.topology import Layer
from tensorflow.python.framework import ops

# training parameters
epochs = 10
batch_size = 3
dim_x = 2
dim_y = 4
N = 100 #half training examples

#define some training data and labels
train_class_0 = np.random.normal(size=(N,dim_x,dim_y)) + 3
train_class_1 = np.random.normal(size=(N,dim_x,dim_y)) - 3
train_data = np.concatenate((train_class_0,train_class_1),axis=0)
output_labels = np.concatenate((0*np.ones(N,),1*np.ones(N,)))

# Define custom function which takes also a grad op as argument:
def ak_py_func(func, inp, Tout, stateful=True, name=None, grad=None):
    # Need to generate a unique name to avoid duplicates:
    rnd_name = 'AkPyFuncGrad' + str(np.random.randint(0, 1E+7))
    tf.RegisterGradient(rnd_name)(grad)
    g = tf.get_default_graph()
    #tf.py_func allows to use a python code as an op
    with g.gradient_override_map({"PyFunc": rnd_name, "PyFuncStateless": rnd_name}):
        return tf.py_func(func, inp, Tout, stateful=stateful, name=name)

# My custom gradient calculation that is wrong
def _MySignGrad(op, grad):
    threshold = 0.01
    newgrad = grad #ok, I guess I cannot do this
    for i in range(batch_size):
        mask = K.ones((op.inputs[i].shape)) #initialize with 1's
        mask[K.abs(op.inputs[i]) > threshold] = 0 #mas is zero when input is above threshold
        newgrad[i] = grad[i] * mask #zero selected gradient entries
    return newgrad

# function that binds forward and backward pass of tensorflow ops
def myfunc(x, name=None):
    with ops.name_scope(name, "Myfunc", [x]) as name:
        output_x = ak_py_func(np.sign, #try also square and exp
                            [x],
                            [tf.float32],
                            name=name,
                            grad=_MySignGrad)  # <-- here's the call to the gradient
        return output_x[0]

#Custom layer
class LimiterLayer(Layer):
    def __init__(self, **kwargs):
        super(LimiterLayer, self).__init__(**kwargs)
    def call(self, x):
        return myfunc(x)
    def get_output_shape_for(self, input_shape):
        return tuple(input_shape)

# Define all layers
l1_input = Input(shape=(dim_x,dim_y),name='l1_input')
l2_flatten = Flatten(name='l2_flatten')(l1_input)
l3_limiter = LimiterLayer(name='l3_limiter')(l2_flatten)
l4_dense = Dense(10, activation='tanh', name='l4_dense')(l3_limiter)
l5_output = Dense(1, activation='sigmoid', name='l5_output') (l4_dense)
# put it all together, creating model from layers
model = Model(l1_input, l5_output)
print(model.summary())
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(train_data, output_labels, epochs=epochs, batch_size=batch_size, validation_split=0.3)

结果如下

public class Student {
    private final String name;
    private final int age;
    private final Country country;
    private final int score;

    // getters and setters (omitted for brevity)
}

public enum Country { POLAND, UK, GERMANY }


//Consider below code snippet 

public static void main(String[] args) {
    List<Student> students = Arrays.asList(
            /*          NAME       AGE COUNTRY          SCORE */
            new Student("Jan",     13, Country.POLAND,  92),
            new Student("Anna",    15, Country.POLAND,  95),
            new Student("Helga",   14, Country.GERMANY, 93),
            new Student("Leon",    14, Country.GERMANY, 97),
            new Student("Chris",    15, Country.GERMANY, 97),
            new Student("Michael", 14, Country.UK,      90),
            new Student("Tim",     15, Country.UK,      91),
            new Student("George",  14, Country.UK,      98)
    );

// Java 8 code to get all countries code but 
// How do I get the only country that has maximum students from ArrayList given above.

    Map<Country, Long> numberOfStudentsByCountry =
            students.stream()
                    .collect(groupingBy(Student::getCountry, counting()));
    System.out.println(numberOfStudentsByCountry);
}

我想要下面的内容。

 {GERMANY=3, POLAND=2, UK=3}

2 个答案:

答案 0 :(得分:2)

您可以使用Stream.max比较以下值来进一步获得地图上最频繁的国家/地区:

Country mostFrequent = numberOfStudentsByCountry.entrySet()
        .stream()
        .max(Map.Entry.comparingByValue())
        .map(Map.Entry::getKey)
        .orElse(Country.POLAND) // some default country

如果您只对单个Map.Entry感兴趣,则可以使用

Map.Entry<Country,Long> mostFrequentEntry = numberOfStudentsByCountry.entrySet()
        .stream()
        .max(Map.Entry.comparingByValue()) // extensible here
        .orElse(null); // you can default according to service

注意 :当您想打破平局之类的要求时,这两种方法都应具有足够的可扩展性,以向Comparator添加自定义逻辑,例如2个国家。举例来说,样本数据中的德国英国之间可能会发生这种情况。

答案 1 :(得分:0)

Map.Entry<Country, Long> maxEntry = students.stream()
          .collect(groupingBy(Student::getCountry, counting()))
          .entrySet().stream().max(Map.Entry.comparingByValue()).get();