задний план
При обработке задания подкачки вам необходимо выполнить операцию округления, например:
// 总数
int totalSize = 799;
// 页大小
int pageSize = 200;
// 计算页数需要向上取整
// 这里的向上取整如何处理?
int pageCount = (double)totalSize / pageSize;
Этот округлый расчет на самом деле очень распространен, но, похоже, не существует стандартного способа его обработки.
общее обращение
Вариант 1: проверить остаток
Проверьте, равен ли остаток 0, это мой обычный способ записи.
// ...
int pageCount = totalSize / pageSize;
if (totalSize % pageSize > 0) {
pageCount++;
}
Этот подход глупый и немного многословный одновременно.
**Вариант 2 (не рекомендуется!): Math.ceil(двойной x) **
Может быть, кто-то уже говорил, что после прочтения первого решения официальный инструмент Math предоставляет метод округления, почему бы им не воспользоваться?
// ...
int pageCount = (int)Math.ceil((double)totalSize / pageSize);
большая проблема:Тип возвращаемого значения Math.ceil — двойной..
Не говоря уже о том, что эта сцена представляет собой две операции с целыми числами, результат также является целым числом, а посередине две операции преобразования типов, что не кажется достаточно гладким, также следует учитывать возможную потерю точности при преобразовании типов. .
Потеря точности может произойти только в экстремальных сценариях, но как только это происходит, это неявная ошибка, которую очень трудно устранить. Например:
- Предположим, что результат вычисления ceil для двух чисел изначально равен 2,0, но из-за проблемы с точностью результат ceil на самом деле равен 1,999999999999999999999999
- При преобразовании результата в данные типа int точность теряется, а результат вычисления преобразуется из 2,0 в 1, что эквивалентно одной странице меньше.
- В процессе пейджинга данные последней страницы отсутствуют
- В процессе воспроизведения такого рода ошибки встречаются лишь в очень редких случаях, и с точки зрения логики кода проблем не возникает.
В качестве другого примера, предполагая, что используется pageCount типа double, следующий фрагмент кода может вызвать исключение ArrayOutOfBoundsException:
// ...
double pageCount = 2d; // 可能实际存储的是2.000000000000001,请意会
for (int page = 0; page < pageCount; page++) {
// Array或List的遍历操作
}
Следует соблюдать осторожность всякий раз, когда могут происходить сравнения с данными с плавающей запятой или преобразования типов между числами с плавающей запятой и целыми числами.
Вариант 3 (рекомендуется): добавить немного обработки
int pageCount = (totalSize + pageSize - 1) / pageSize;
Этот метод вычислений решается в одной строке кода, нет преобразования типов или потери точности, а обработка представляет собой идею переноса, которая очень естественна, если вы ее понимаете.
Единственным недостатком является то, что он может переполниться, если значение слишком велико, но этого достаточно для большинства сценариев.
Пополнить
Почему Math.ceil возвращает число с плавающей запятой?
да, вернисьцелое число с плавающей запятойХотя он соответствует семантике ceil, он не соответствует нашему обычному интуитивному пониманию Насколько хорошо было бы, если бы он мог возвращать целое число?
Однако входным параметром этого метода является тип double, а диапазон представления типа int или long намного меньше, чем диапазон типа double.Если используется целочисленный тип, он может не быть представлен, тем самым вызывая эту странную реальность.
Диапазон представлений см.использованная литература.
Удобный метод сегментации списка
Я думал об этом в середине написания, на самом деле мой сценарий обработки на этот раз состоит в том, чтобы горизонтально разделить данные списка общей задачи на несколько списков подзадач, а затем распределить их.
Если это сценарий сегментации для списка, настоятельно рекомендуется использовать пакет Google guava для обработки:
// 直接分割,非常方便
List<List<Object>> subTaskLists = Lists.partition(taskList, pageSize);
Реализация Lists.partition: фиксированный размер шага, брать подсписок несколько раз.
использованная литература
java - Округление Java до int с использованием Math.ceil - Qaru QaruSite
Диапазон значений short, int, long, float и double в java — блог qfikh — блог CSDN
Эта статья адаптирована измой блог, добро пожаловать в гости!