Как бы вы обновили значения в хэш-карте на основе предыдущих условий? - PullRequest
0 голосов
/ 30 апреля 2018

Мне сложно понять что-то фундаментальное в хэш-картах и ​​циклах. Я пытаюсь добавить +1 к значению, связанному с ключом на основе метода Keys, каждый раз, когда значение в списке массивов связано со строкой ключа.

Таким образом, если в списке массивов есть 3 значения, которые являются положительными, то в хэш-карте должно быть значение с ключом «Positive», обновленным до 3.

Буду признателен за любую помощь / совет - спасибо.

public String Keys(double input){

    if (input > 0){
        System.out.println("positive");
    }
    else if (input < 0) {
        System.out.println("negative");
    }
    else if (input == 0) {
        System.out.println("zero");
    }
    return "";
}

public HashMap<String, Integer> increaseValues(ArrayList<Double> inputs){
    HashMap<String, Integer> hashMap = new HashMap<>();
    hashMap.put("positive", 0);
    hashMap.put("negative", 0);
    hashMap.put("zero", 0);

//What I tried before adding the Keys method.
//This updates the value but the loop won't continue if another input in the 
//arraylist is true.

for (int i = 0; i < inputs.size(); i++){
        double input = inputs.get(i);

        if (input > 0){
           hashMap.put("positive", 1);
        } else if (input < 0){
          hashMap.put("negative", 1);
        } else if (input == 0){
          hashMap.put("zero", 1); }
    return hashMap;
}

public void main(String[] args){
    ArrayList<Double> inputs = new ArrayList<>();
    inputs.add(-4.56);
    inputs.add(-4.66);
    inputs.add(0.0);
    inputs.add(6.0);
    inputs.add(-6.99);
    inputs.add(6.97);   
}

Ответы [ 4 ]

0 голосов
/ 30 апреля 2018

Вы можете решить это довольно кратко с помощью потоков. Вам нужна функция, которая превращает значение в клавишу negative / zero / positive. Затем просто сгруппируйте по этому ключу счетный коллектор. Это в основном двухслойный:

    List<Double> values = Arrays.asList(-4.56,-4.66,0.0, 6.0, -6.99, 6.97);

    Function<Double, String> toKey = v -> v < 0 ? "negative" : (v == 0 ? "zero" : "positive");

    Map<String, Long> result = values
        .stream()
        .collect(Collectors
            .groupingBy(
                 toKey,
                 Collectors.counting()));
0 голосов
/ 30 апреля 2018

Map.put(k, v) всегда отменяет ваше предыдущее значение. Вы можете использовать «традиционный подход»:

if (!map.containsKey("positive"))
    map.put("positive", 0);
map.put("positive", map.get("positive") + 1);

или лучше используйте новую merge функцию, добавленную именно для таких случаев:

map.merge("positive", 1, (prev, one) -> prev + one);

Но вся эта логика может быть значительно сокращена с помощью Math.signum() и потоковых сборщиков:

Map<Double, Long> collect = inputs.stream()
                                  .collect(Collectors.groupingBy(Math::signum,
                                                                 Collectors.counting()));
System.out.println("positive: " + collect.get(1.0));
System.out.println("negative: " + collect.get(-1.0));
System.out.println("zero: " + collect.get(0.0));
0 голосов
/ 30 апреля 2018

Давайте начнем с быстрой уборки, давайте создадим enum и удалим те неприятные String константы, которые вы нигде не определили:

public enum Sign {
    POSITIVE,
    ZERO,
    NEGATIVE;

    public static Sign of(double d) {
        if (d > 0) {
            return POSITIVE;
        }
        if (d < 0) {
            return NEGATIVE;
        }
        return ZERO;
    }
}

Теперь мы можем тривиально написать метод для увеличения соответствующего значения:

public void increment(final double d, final Map<Sign, Integer> count) {
    count.merge(Sign.of(d), 1, Integer::sum);
}

Для быстрого теста:

final Map<Sign, Integer> count = new EnumMap<>(Sign.class);

increment(0, count);
System.out.println(count);
increment(-1, count);
System.out.println(count);
increment(1, count);
System.out.println(count);
increment(-2, count);
System.out.println(count);
increment(2, count);
System.out.println(count);

Выход:

{ZERO=1}
{NEGATIVE=1, ZERO=1}
{POSITIVE=1, NEGATIVE=1, ZERO=1}
{POSITIVE=1, NEGATIVE=2, ZERO=1}
{POSITIVE=2, NEGATIVE=2, ZERO=1}

Так как же работает эта магия? С документация для Map.merge

Если указанный ключ еще не связан со значением или является связанный с нулем, связывает его с заданным ненулевым значением. В противном случае заменяет ассоциированное значение на результаты данного функция переназначения или удаляет, если результат нулевой. Этот метод может быть полезным при комбинировании нескольких сопоставленных значений для ключа.

Таким образом, key принимает в качестве первого аргумента merge - в случае Sign.of(d); это выбирает правильное ведро. Если значение, сопоставленное этому key, равно null, то оно просто помещает сопоставление для key в value, переданное в качестве второго аргумента - в данном случае 1. Иначе это становится немного сложнее; он принимает значение, сопоставленное с этим ключом, и использует remappingFunction, переданный в качестве третьего аргумента Это BiFunction<V,V,V>, поэтому он принимает два аргумента типа V, типа value и возвращает один - он объединяет два вместе. Здесь мы используем Integer::sum, чтобы взять существующие value, новые value и вернуть их sum.


Но мы можем пойти еще дальше, мы можем использовать Stream, чтобы выполнить это на произвольной double[]:

public Map<Sign, Long> count(final double[] d) {
    return Arrays.stream(d)
            .mapToObj(Sign::of)
            .collect(groupingBy(identity(), () -> new EnumMap<>(Sign.class), counting()));
}

Примечание: здесь я использовал EnumMap, который Map оптимизирован для использования enum в качестве ключа.

0 голосов
/ 30 апреля 2018

Метод put HashMap отображает уникальные ключи со значениями. Он заменяет существующее значение новым значением, если указанный ключ уже присутствует на карте.

Вам необходимо определить метод, аналогичный приведенному ниже.

public void addValueToList(Double d, List<Double> inputs , Map<String,Integer> map){
    if( d == null ) return;
    if ( isZero(d) ){
        Integer count =  map.get("zero");
        if(count == null){
            count = 1;
        }else {
             count ++;
        }
        map.put("zero",count);

    }else if( isNegative(d) ) {
        Integer count =  map.get("negative");
        if(count == null){
            count = 1;
        }else {
             count ++;
        }
        map.put("negative",count);
    }else {
        Integer count =  map.get("positive");
        if(count == null){
            count = 1;
        }else {
             count ++;
        }
        map.put("positive",count);
   }
   inputs.add(d);
}

Для написания метода сравнения значений вы можете обратиться https://stackoverflow.com/a/10400718/504133

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...