Большинство операций, связанных с байтом, автоматически повышаются до int. Например, рассмотрим простой метод, который добавляет константу byte
к каждому элементу массива byte[]
, возвращающему новый массив byte[]
(потенциальный кандидат для ByteStream
):
public static byte[] add(byte[] arr, byte addend) {
byte[] result = new byte[arr.length];
int i=0;
for(byte b : arr) {
result[i++] = (byte) (b+addend);
}
return result;
}
См. даже если мы выполняем добавление двух переменных byte
, они расширяются до int
, и вам нужно вернуть результат в byte
. В байт-коде Java большинство операций, связанных с byte
(кроме загрузки / хранения массива и байт-байт), выражаются с помощью 32-разрядных целых инструкций (iadd
, ixor
, if_icmple
и т. Д.). Таким образом, практически нормально обрабатывать байты как int с IntStream
. Нам просто нужны две дополнительные операции:
IntStream
из массива byte[]
(расширяя байты до int) IntStream
в byte[]
(используя (byte)
литье) Первый из них очень прост и может быть реализован следующим образом:
public static IntStream intStream(byte[] array) {
return IntStream.range(0, array.length).map(idx -> array[idx]);
}
Таким образом, вы можете добавить такой статический метод к своему проект и быть счастливым.
Сбор потока в массив byte[]
более сложный. Использование стандартных классов JDK самым простым решением является ByteArrayOutputStream
:
public static byte[] toByteArray(IntStream stream) {
return stream.collect(ByteArrayOutputStream::new, (baos, i) -> baos.write((byte) i),
(baos1, baos2) -> baos1.write(baos2.toByteArray(), 0, baos2.size()))
.toByteArray();
}
Однако из-за синхронизации у него нет лишних накладных расходов. Также было бы неплохо специально обработать потоки известной длины, чтобы уменьшить выделение и копирование. Тем не менее теперь вы можете использовать Stream API для массивов byte[]
:
public static byte[] addStream(byte[] arr, byte addend) {
return toByteArray(intStream(arr).map(b -> b+addend));
}
В моей библиотеке StreamEx есть обе эти операции в IntStreamEx
, который улучшает стандарт IntStream
, поэтому вы можете использовать его следующим образом:
public static byte[] addStreamEx(byte[] arr, byte addend) {
return IntStreamEx.of(arr).map(b -> b+addend).toByteArray();
}
Метод internally toByteArray()
использует простой изменяемый размер байт-буфер и специально обрабатывает случай, когда поток является последовательным, и размер цели известен заранее.
Обновленный для возврата текущего года плюс предыдущие 5 лет. Должно быть очень быстрым, поскольку это - маленький recordset.
SELECT YEAR(GETDATE()) as YearNum
UNION
SELECT YEAR(GETDATE()) - 1 as YearNum
UNION
SELECT YEAR(GETDATE()) - 2 as YearNum
UNION
SELECT YEAR(GETDATE()) - 3 as YearNum
UNION
SELECT YEAR(GETDATE()) - 4 as YearNum
UNION
SELECT YEAR(GETDATE()) - 5 as YearNum
ORDER BY YearNum DESC
Используя ROW_NUMBER
на любом столбце от любого достаточно большая (стабильная) таблица была бы одним способом сделать это.
SELECT *
FROM (
SELECT TOP 100 2003 + ROW_NUMBER() OVER (ORDER BY <AnyColumn>) AS Yr
FROM dbo.<AnyTable>
) Years
WHERE Yr <= YEAR(GETDATE())
Примечание, которое <AnyTable>
должно содержать, по крайней мере, сумму строк, равных на сумму лет, которых Вы требуете.
system table
должно прийти на ум. CTE
как упомянутый в ответе, данном Joshua. CTE
техника намного выше и менее подвержена ошибкам, чем текущий, учитывая ROW_NUMBER
решение. SET NOCOUNT ON
DECLARE @max int
set @max = DATEPART(year, getdate())
CREATE TABLE #temp (val int)
while @max >= 2004
BEGIN
insert #temp(val) values(@max)
set @max = @max - 1
END
SELECT * from #temp
DECLARE @YEARS TABLE (Y INT)
DECLARE @I INT, @NY INT
SELECT @I = 2004, @NY = YEAR(GETDATE())
WHILE @I <= @NY BEGIN
INSERT @YEARS SELECT @I
SET @I = @I + 1
END
SELECT Y
FROM @YEARS
ORDER BY Y DESC
Попробуйте это:
declare @lowyear int
set @lowyear = 2004
declare @thisyear int
set @thisyear = year(getdate())
while @thisyear >= @lowyear
begin
print @thisyear
set @thisyear = (@thisyear - 1)
end
Возвраты
2009
2008
2007
2006
2005
2004
, Когда Вы поражаете Jan 1, 2010. Тот же код возвратится:
2010
2009
2008
2007
2006
2005
2004
Я думаю, что необходимо составить таблицу дат, тогда просто выбрать диапазон от него. Это может также пригодиться, когда необходимо выбрать диапазон дат с X присоединенными данными и не иметь любые пропущенные дни.