Как я могу установить следующий день? Если мое предупреждение прошло? [Дублировать]

Вы можете следовать идеям, описанным в . Как реализовать HashMap с двумя ключами? . Вот ответ «заимствованный объект-объект», ответ на ваш случай:

Создайте признак, который мы можем использовать в качестве общей цели Borrow:

trait Key {
    fn to_key(&self) -> (i32, &str);
}

Реализовать HashMap -приобретенные черты для объекта-объекта:

use std::hash::{Hash, Hasher};

impl<'a> Hash for Key + 'a {
    fn hash(&self, state: &mut H) {
        self.to_key().hash(state)
    }
}

impl<'a> PartialEq for Key + 'a {
    fn eq(&self, other: &Self) -> bool {
        self.to_key() == other.to_key()
    }
}

impl<'a> Eq for Key + 'a {}

Реализовать признак для нашего основного типа и любых типов вторичного поиска:

impl Key for Complex {
    fn to_key(&self) -> (i32, &str) {
        (self.n, &self.s)
    }
}

impl<'a> Key for (i32, &'a str) {
    fn to_key(&self) -> (i32, &str) {
        (self.0, self.1)
    }
}

Реализовать Borrow для всех типов поиска, возвращающих наш объект-объект:

use std::borrow::Borrow;

impl<'a> Borrow for Complex {
    fn borrow(&self) -> &(Key + 'a) {
        self
    }
}

impl<'a> Borrow for (i32, &'a str) {
    fn borrow(&self) -> &(Key + 'a) {
        self
    }
}

Преобразовать объект-объект во время запроса:

assert_eq!(Some(&123), m.get((42, "foo").borrow() as &Key));

Полный код в playground


Важным «полученным» является то, что весь ваш первичный ключ и ваши вторичные ключи должны иметь хэш таким же образом. Это означает, что одни и те же значения должны идти в вычисление хэша в том же порядке и количестве.

Вы можете определить Hash вручную, чтобы убедиться, что ваш основной и дополнительный ключи hash одинаковы!

Вот еще один пример, на этот раз с перечислением:

#[derive(Debug, PartialEq, Eq)]
enum ConfigKey {
    Text(String),
    Binary(Vec),
}

Мы создаем параллельное перечисление, состоящее только из ссылок, поэтому его легко создать. Важно, чтобы мы определяли одни и те же варианты и в том же порядке, что и первичное перечисление, чтобы они были хэшированы одинаково. Мы полагаемся на то, что хеш String и &str использует тот же алгоритм, что и Vec и &[T]:

impl ConfigKey {
    fn as_ref(&self) -> ConfigKeyRef {
        match self {
            ConfigKey::Text(t) => ConfigKeyRef::Text(t),
            ConfigKey::Binary(b) => ConfigKeyRef::Binary(b),
        }
    }
}

#[derive(Hash, PartialEq, Eq)]
enum ConfigKeyRef<'a> {
    Text(&'a str),
    Binary(&'a [u8]),
}

Мы используем это новое перечисление как наш общий базовый тип ключа :

trait Key {
    fn to_key(&self) -> ConfigKeyRef;
}

И реализуем нашу черту для наших первичных и вторичных ключей:

impl Key for ConfigKey {
    fn to_key(&self) -> ConfigKeyRef {
        self.as_ref()
    }
}

impl<'a> Key for &'a str {
    fn to_key(&self) -> ConfigKeyRef {
        ConfigKeyRef::Text(self)
    }
}

Полный код на игровой площадке

7
задан Flame of udun 10 April 2016 в 21:52
поделиться

1 ответ

Вам не нужно создавать Timestamp s. Вы можете сделать это с помощью Calendar.

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
calendar.set(Calendar.MINUTE, minute);

if(calendar.before(Calendar.getInstance())) {
    calendar.add(Calendar.DATE, 1);
}

alarmManager.set(AlarmManager.RTC_WAKEUP,
    calendar.getTimeInMillis(), pendingDinnerIntent);

Я бы также упомянул, что с KitKat, если ваш targetSdkVersion равен 19 или выше, метод AlarmManager#set() не является точным. Если вы хотите, чтобы ваш будильник срабатывал в определенное время, вам нужно использовать метод setExact*().

19
ответ дан Mike M. 28 August 2018 в 03:10
поделиться
Другие вопросы по тегам:

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