Все переменные, содержащие объекты, такие как списки, по сути являются указателями (придирки могут не согласиться с точной терминологией, но я уверен, что это достаточно близко). Поэтому, когда вы говорите
this.allCustomers = parent.allCustomers
, this.allCustomers и parent.allCustomers теперь указывают на один и тот же объект List. Затем
this.allCustomers.remove(currentCustomer)
запускает .remove () в этом списке ... который является allCustomers родителя ... который в настоящее время перебирается. Поскольку список изменяется, итерация не выполняется.
Чтобы пояснить комментарий, сделанный по этому вопросу, «Java на 100% передается по значению. Ссылки на объекты передаются по значению». означает, что вы не можете реализовать функцию «swap» из языка C [1] sup>, потому что функция получает копии (значения) указателей / ссылок и не может изменять значения оригиналов, но функция может изменить свойства объекта, указателю / ссылке которого он дан, и сделать эти изменения видимыми для вызывающего абонента, который передал объект, потому что они ссылаются на один и тот же объект. Примитивные типы (int, boolean и т. Д.) Передаются по значению, но они неизменны (можно сказать, x = 3, а затем x = 5, но не существует 3.changeValueTo (5)), поэтому разницу можно в значительной степени игнорировать.
···
[1]: это запрещает использование класса Unsafe, который имеет прямой доступ к памяти. Не используйте это, поскольку это может серьезно сломать вещи. Умным инженерам, которые могут использовать его навсегда (например, иногда его используют внутренние Java-компоненты), в любом случае, мне не понадобится мой совет.
#!/bin/sh
die () {
echo >&2 "$@"
exit 1
}
[ "$#" -eq 1 ] || die "1 argument required, $# provided"
echo $1 | grep -E -q '^[0-9]+$' || die "Numeric argument required, $1 provided"
while read dir
do
[ -d "$dir" ] || die "Directory $dir does not exist"
rm -rf "$dir"
done <<EOF
~/myfolder1/$1/anotherfolder
~/myfolder2/$1/yetanotherfolder
~/myfolder3/$1/thisisafolder
EOF
править: Я пропустил часть о проверке, если каталоги существуют сначала, таким образом, я включил это, завершив сценарий. Кроме того, решили вопросы, поднятые в комментариях; зафиксированный регулярное выражение, переключенное с ==
кому: eq
.
Это должно быть портативным устройством, POSIX совместимый сценарий насколько я могу сказать; это не использует bashisms, который на самом деле важен потому что /bin/sh
на Ubuntu на самом деле dash
в эти дни, нет bash
.
Я использовал бы удар [[
:
if [[ ! ("$#" == 1 && $1 =~ ^[0-9]+$ && -d $1) ]]; then
echo 'Please pass a number that corresponds to a directory'
exit 1
fi
Я нашел, что эти часто задаваемые вопросы были хорошим источником информации.
sh
решение Brian Campbell
, в то время как благородный и хорошо выполняемый, имеет несколько проблем, таким образом, я думал, что обеспечу свое собственное bash
решение.
Проблемы с sh
один:
~/foo
не расширяется до Вашего homedirectory внутри heredocs. И ни один, когда это читается read
оператор или заключенный в кавычки в rm
оператор. Что означает, что Вы доберетесь No such file or directory
ошибки.grep
и такой для основных операций ненормален. Особенно, когда Вы используете дрянную оболочку для предотвращения "тяжелого" веса удара.echo
.sh
может справиться с ними - который является, почему я почти всегда предпочитаю bash
, это является намного более пуленепробиваемым и более твердым использовать при использовании хорошо).В то время как, да, с помощью /bin/sh
поскольку Ваш hashbang означает, что необходимо избежать bash
измы любой ценой, можно использовать весь bash
измы, которые Вы любите, даже на Ubuntu или этажерке, когда Вы честны и помещаетесь #!/bin/bash
наверху.
Так, вот a bash
решение это является меньшим, более чистым, более прозрачным, вероятно, "быстрее", и более пуленепробиваемым.
[[ -d $1 && $1 != *[^0-9]* ]] || { echo "Invalid input." >&2; exit 1; }
rm -rf ~/foo/"$1"/bar ...
$1
в rm
оператор!-d
проверка также перестанет работать если $1
пусто, таким образом, это - две регистрации один.=~
в ударе необходимо помещать регулярное выражение в переменную. В любом случае шарики как мои всегда предпочтительны и поддерживаются в намного большем количестве версий удара.Не столь пуленепробиваемый как вышеупомянутый ответ, однако все еще эффективный:
#!/bin/bash
if [ "$1" = "" ]
then
echo "Usage: $0 <id number to be cleaned up>"
exit
fi
# rm commands go here
Используйте '-z' для тестирования на пустые строки и '-d для проверки на каталоги.
if [[ -z "$@" ]]; then
echo >&2 "You must supply an argument!"
exit 1
elif [[ ! -d "$@" ]]; then
echo >&2 "$@ is not a valid directory!"
exit 1
fi
Страница справочника для теста (man test
) обеспечивает все доступные операторы, которые можно использовать в качестве булевых операторов в ударе. Используйте те флаги в начале Вашего сценария (или функции) для контроля ввода точно так же, как Вы были бы на любом другом языке программирования. Например:
if [ -z $1 ] ; then
echo "First parameter needed!" && exit 1;
fi
if [ -z $2 ] ; then
echo "Second parameter needed!" && exit 2;
fi
Вы можете компактно проверить точки a и b, выполнив что-то вроде следующего:
#!/bin/sh
MYVAL=$(echo ${1} | awk '/^[0-9]+$/')
MYVAL=${MYVAL:?"Usage - testparms <number>"}
echo ${MYVAL}
Что дает нам ...
$ ./testparams.sh
Usage - testparms <number>
$ ./testparams.sh 1234
1234
$ ./testparams.sh abcd
Usage - testparms <number>
Этот метод должен работать нормально в ш.