Становится немного длиннее, но вот тот, который сочетает в себе рекурсивность решения Гарретта с npe-безопасностью исходного вопроса.
def deleteFile(path: String) = {
val penultimateFile = new File(path.split('/').take(2).mkString("/"))
def getFiles(f: File): Set[File] = {
Option(f.listFiles)
.map(a => a.toSet)
.getOrElse(Set.empty)
}
def getRecursively(f: File): Set[File] = {
val files = getFiles(f)
val subDirectories = files.filter(path => path.isDirectory)
subDirectories.flatMap(getRecursively) ++ files + penultimateFile
}
getRecursively(penultimateFile).foreach(file => {
if (getFiles(file).isEmpty && file.getAbsoluteFile().exists) file.delete
})
}
Если повышенным типом левого операнда является int, только пять младших битов правого операнд используется как расстояние сдвига. Это как если бы правый операнд был подвергнут побитовой логической операции AND & (§15.22.1) со значением маски 0x1f. Таким образом, фактически используемое расстояние сдвига всегда находится в диапазоне от 0 до 31 включительно.
Таким образом, если b - это int, выражение идентично
long a = b | c;
, что я очень сомневаюсь в том, что предназначено. Вероятно, это должно было быть
long a = ((long) b << 32) | c;
(если b уже является длинным, код правильный и FindBugs ошибается в отношении ошибки).
Отредактировано: Проблема почти наверняка проистекает из того факта, что 'b' - это 'int' а не «длинное».
В C, если «b» является целым числом вместо длинного, и вы сдвигаетесь влево на 32 бита, все биты из исходного значения были удалены, поэтому результат общее выражение будет таким же, как 'c' , вы вызовете неопределенное поведение, поэтому любой результат допустим. Java определяет вещи по-разному - как отмечено в комментарии Расмуса Фабера и выбранном ответе - и выполняет сверхдлинные сдвиги по модулю максимального количества бит, которое может быть сдвинуто. [Это кажется странным способом ведения бизнеса; Я бы, наверное, устроил исключение для языка, на котором они есть. Однако четко определено, что более важно, чем точное определение.] Принуждение к 64-битным не происходит, пока выражение оценивается; это происходит, когда выражение завершено и происходит присваивание.
Ссылка на 5 битов ... интригует. Это означает, что если вы сдвинете влево, скажем, на 48 или на двоичное 110000, это будет то же самое, что сдвинуть влево на 16. Или, альтернативно, ' x << n
' будет таким же, как ' x << (n% 32)
'.