Дженерики Java и (сопоставимая) бесконечность

Попробуйте это ...

HTML

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
<input type="text" id="PW1" size="20" name="PW1" value="$PW1" required>
    <button onclick="getRndInteger(10000,99999)">Assign Random Password</button>
</body>
</html>

JS

function getRndInteger(min, max) {
  var myRandomNumber = Math.floor(Math.random() * (max - min)) + min;
  document.getElementById('PW1').value = myRandomNumber;
}
5
задан Flavio Martins 29 April 2009 в 19:09
поделиться

10 ответов

Это не имеет никакого смысла ...

Учитывая, что вы не знаете, что такое K на тот момент (т. Е. Вы реализуете это в общем ... дух!), Вы не можете указать мин / макс ограничен для него.

В случае, когда K может быть int, длинным, строковым объектом OR, вы не могли разумно предположить использовать

Integer.MIN_VALUE, "" OR NULL.

I угадайте, что вы ищете, это K.MIN_VALUE_OF_EVENTUAL_TYPE, но его не существует.

4
ответ дан 18 December 2019 в 07:10
поделиться

Я пытаюсь представить, какой сценарий потребует такого поведения. Это лучшее, что я могу придумать ...

ВНИМАНИЕ: Этот код опасен. Пожалуйста, будь милостив ко мне за публикацию такой мерзости. Это только подтверждение концепции.

public class Lowest<K> implements Comparable<K> {
    public int compareTo(K other) {
        return -1;
    }
}

А потом ...

public class Test {
    public <K extends Comparable<K>> K findMaximum(List<K> values) throws Exception {
        K lowest = (K) new Lowest<K>(); /// XXX DANGER! Losing compile-time safety!!!

        K maximum = lowest;
        for (K value : values) {
            if (maximum.compareTo(value) < 0) {
                maximum = value;
            }
        }

        if (maximum == lowest) {
            throw new Exception("Could not find a maximum value");
        } else {
            return maximum;
        }
    }
}
4
ответ дан 18 December 2019 в 07:10
поделиться

Uh doesn't this depend on what type K is?

The point of Generics is that K can be any type (or any subclass of a certain type); in order to be able to call methods on K or access properties of it, you need to restrict it's type bounds with wildcards.

1
ответ дан 18 December 2019 в 07:10
поделиться

Не существует универсальной формы MIN_VALUE или MAX_VALUE для всех сопоставимых типов.

Подумайте о классе Time это реализует сопоставимые. Не существует MAX_VALUE для времени, даже если оно сопоставимо.

4
ответ дан 18 December 2019 в 07:10
поделиться

Consider not making K a generic, but using an interface that wraps the primitive wrapper (a double wrapper!).

import java.util.HashMap;


public class NodeWrapper<K extends Comparable<K>> implements Comparable<NodeWrapper<K>> {

    private static HashMap<Class, NodeWrapper> minVals = new HashMap<Class, NodeWrapper>();

    private K value;

    private NodeWrapper() {
        super();
    }

    public NodeWrapper(K value, Class<K> clazz) {
        super();
        this.value = value;

        if (minVals.get(clazz)==null) {
            minVals.put(clazz, new NodeWrapper<K>());
        }
    }

    public K getValue() {
        return value;
    }

    public static NodeWrapper getMinValue(Class clazz){
        return minVals.get(clazz);
    }

    public void setValue(K value) {
        this.value = value;
    }

    @Override
    public int compareTo(NodeWrapper<K> o) {
        NodeWrapper min = minVals.get(this.getClass());
        if (this==min && o==min)  {
            return 0;
        } else if (this==min){
            return -1;
        } else if (o==min){
            return 1;
        } else {
            return this.value.compareTo(o.value);
        }
    }

}

Briefly, the idea is that whenever a new class is instantiated, a minimum value is created and put into a static hashmap that stores the minimum values for each class. (In fact, these values are NOTHING at all, just a sentinel object, but since we will use object equality to determine if something is the min value, this is no problem at all.) All that's necessary is that the wrapped object be comparable to other instances of itself in general.

One drawback is that when you call getMinValue you will have compiler warnings, since the return type will have no generic information. There may be a more elegant way around this, but I can't think of it right now.

This general idea might be rather nice overall. However, I should really stress: this will absolutely break if you try it with any polymorphism or any mixing of mutually comparable classes. Longs and Integers in the same tree will completely destroy you.

1
ответ дан 18 December 2019 в 07:10
поделиться

только то, что объект является сопоставимым, не означает, что он должен иметь минимальное значение. Причина, по которой int имеет минимальное значение - (2 ^ (31)), заключается в том, что для знака требуется 1 бит, поэтому 2 ^ 31 - это наибольшее (или наименьшее) возможное целое число, которое можно сохранить. Для таких вещей, как строка, это не имеет никакого смысла, так как нет наибольшей / наименьшей возможной строки, она ограничена памятью.

1
ответ дан 18 December 2019 в 07:10
поделиться

Возможно, вам придется создать интерфейс «IInfinity», чтобы K расширял IInfinity и IInfinity, чтобы иметь метод «getInfinityValue ()», а затем упаковывал / расширял Integer, Double, BigDecimal, и т.д. в классе, который реализует IInfinity ... и тьфу!

1
ответ дан 18 December 2019 в 07:10
поделиться

По сути, вы хотите, чтобы любой тип K реализовывал некоторые статические функции, скажем, самые низкие и самые высокие, которые подчиняются стандартным математическим свойствам.

Я предполагаю, что это чувство самого низкого (или самого высокого) можно использовать Вы хотели бы, чтобы у любого сопоставимого объекта были эти методы. (или статические поля). Если вас интересуют только ваши собственные пользовательские объекты, способ сделать это состоял бы в том, чтобы все наследовало от абстрактного типа данных, который объявил статические поля для MINVALUE и MAX_VALUE, а затем ваш тип varaible. Если вам нужна эта функциональность для других классов, вам нужно создать какой-то внешний хэш-файл, который отслеживает эти свойства для разных классов (но это может быть довольно уродливо)

1
ответ дан 18 December 2019 в 07:10
поделиться

Вы можете создать класс-оболочку, который «добавляет» минимальное и максимальное значение для всех типов. Он просто имеет два статических экземпляра, которые представляют минимальный и максимальный значения, а затем другие экземпляры оборачивают какое-то другое значение некоторого типа. Когда мы делаем сравнение, мы проверяем, является ли одна из вещей минимальным или максимальным, и возвращаем правильный результат; и иначе мы просто делаем то же самое сравнение как базовый тип. Примерно так:

class Extended<T extends Comparable<? super T>> implements Comparable<Extended<T>> {
    private Extended() { }

    private static Extended min = new Extended();
    private static Extended max = new Extended();

    @SuppressWarnings("unchecked")
    public static <T extends Comparable<? super T>> Extended<T> getMin() {
        return (Extended<T>)min;
    }
    @SuppressWarnings("unchecked")
    public static <T extends Comparable<? super T>> Extended<T> getMax() {
        return (Extended<T>)max;
    }

    public T value;

    public Extended(T x) { value = x; }

    public int compareTo(Extended<T> other) {
        if (this == other) return 0;
        else if (this == min || other == max) return -1;
        else if (this == max || other == min) return 1;
        else return this.value.compareTo(other.value);
    }
}
3
ответ дан 18 December 2019 в 07:10
поделиться

На случайный случай вам действительно понадобится строка беззнаковых символов,

2
ответ дан 18 December 2019 в 07:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: