Это ошибка из-за оптимизации в bash.
При замене шаблона bash first проверяет, соответствует ли шаблон в любом месте в строке. Если это не так, тогда нет смысла выполнять поиск и замену. То, как он это делает, - построить новый шаблон, поместив его с помощью *..*
по мере необходимости:
/* If the pattern doesn't match anywhere in the string, go ahead and
short-circuit right away. A minor optimization, saves a bunch of
unnecessary calls to strmatch (up to N calls for a string of N
characters) if the match is unsuccessful. To preserve the semantics
of the substring matches below, we make sure that the pattern has
`*' as first and last character, making a new pattern if necessary. */
/* XXX - check this later if I ever implement `**' with special meaning,
since this will potentially result in `**' at the beginning or end */
len = STRLEN (pat);
if (pat[0] != '*' || (pat[0] == '*' && pat[1] == LPAREN && extended_glob) || pat[len - 1] != '*')
{
int unescaped_backslash;
char *pp;
p = npat = (char *)xmalloc (len + 3);
p1 = pat;
if (*p1 != '*' || (*p1 == '*' && p1[1] == LPAREN && extended_glob))
*p++ = '*';
Образец, который он пытается сопоставить со строкой, заканчивается *(*
Открытие *(
теперь непреднамеренно распознается как начало extglob, но когда bash не находит закрытие )
, оно соответствует шаблону в виде строки:
prest = PATSCAN (p + (*p == L('(')), pe, 0); /* ) */
if (prest == 0)
/* If PREST is 0, we failed to scan a valid pattern. In this
case, we just want to compare the two as strings. */
return (STRCOMPARE (p - 1, pe, s, se));
Это означает, что если строка, в которой выполняются замены, буквально *(*
, оптимизация неверно отклоняет строку, считая, что делать нечего. Разумеется, это также означает, что он корректно работает для самого *(*
:
$ f='*(*'; echo "${f//(/\\(}"
*\(*
Если вы хотите выманить эту проверку оптимизации в исходном коде:
diff --git a/subst.c b/subst.c
index fc00cab0..f063f784 100644
--- a/subst.c
+++ b/subst.c
@@ -4517,8 +4517,6 @@ match_upattern (string, pat, mtype, sp, ep)
c = strmatch (npat, string, FNMATCH_EXTFLAG | FNMATCH_IGNCASE);
if (npat != pat)
free (npat);
- if (c == FNM_NOMATCH)
- return (0);
len = STRLEN (string);
end = string + len;
, тогда он будет корректно работать в вашем случае:
$ ./bash -c 'f="my string(1) with (parens)"; echo "${f//(/\\(}"'
my string\(1) with \(parens)
Ссылка, которую вы передаете в ArrayAdapter, отличается от той, которая назначена здесь:
listAssignments = sPetInformationViewModel.getAssignedProviders(petId);
Что касается ArrayAdapter, то listAssignments, к которым он имеет ссылку, очищен OnResume, и ничего не было добавлено вернемся к этому. Он ничего не знает о новой ссылке listAssignments.
Попробуйте сделать это:
public void onResume()
{
super.onResume();
Log.d(TAG, "Entered: onResume");
listAssignments.clear();
Log.d(TAG, "listAssignments is: " + listAssignments);
List<Assignment> newList = sPetInformationViewModel.getAssignedProviders(petId);
listAssignments.addAll(newList);
mAdapter.notifyDataSetChanged();
}
Хорошо, я собираюсь выйти из этого вопроса и сказать, что notifyDataSetChanged () не работает для ArrayList, потому что при каждой загрузке его адрес меняется, см. Мой оригинальный пост и комментарии к pnavk, чтобы увидеть детали. Насколько я понимаю, Java не предоставляет средств для установки в камне адреса ArrayList, как это делает C или C ++ через указатель, поэтому Adapter устанавливается в ячейку памяти исходного объекта ArrayList и поэтому указывает на одни и те же данные на каждом Вызов notifyDataSetChanged (), даже несмотря на то, что Java использовала новую ячейку памяти для этого объекта ArrayList или создала новый объект ArrayList с тем же именем.
Поэтому, мой ответ для обновления RecyclerView из нового набора данных в ArrayList должен сбросить Adapter в onResume как новый и затем переназначить этот Adapter для вашего RecyclerView, как я упоминал в моем ответе на pnavk:
[110 ]