В случае ArrayList: remove (int index) - если (индекс - позиция последнего элемента), он избегает без System.arraycopy()
и не занимает времени для этого.
Время arraycopy увеличивается, если (индекс уменьшается), кстати, элементы списка также уменьшаются!
лучший эффективный способ удаления - удаление его элементов в порядке убывания: while(list.size()>0)list.remove(list.size()-1);
// принимает O (1) while(list.size()>0)list.remove(0);
// принимает O (факториал ( n))
//region prepare data
ArrayList<Integer> ints = new ArrayList<Integer>();
ArrayList<Integer> toRemove = new ArrayList<Integer>();
Random rdm = new Random();
long millis;
for (int i = 0; i < 100000; i++) {
Integer integer = rdm.nextInt();
ints.add(integer);
}
ArrayList<Integer> intsForIndex = new ArrayList<Integer>(ints);
ArrayList<Integer> intsDescIndex = new ArrayList<Integer>(ints);
ArrayList<Integer> intsIterator = new ArrayList<Integer>(ints);
//endregion
// region for index
millis = System.currentTimeMillis();
for (int i = 0; i < intsForIndex.size(); i++)
if (intsForIndex.get(i) % 2 == 0) intsForIndex.remove(i--);
System.out.println(System.currentTimeMillis() - millis);
// endregion
// region for index desc
millis = System.currentTimeMillis();
for (int i = intsDescIndex.size() - 1; i >= 0; i--)
if (intsDescIndex.get(i) % 2 == 0) intsDescIndex.remove(i);
System.out.println(System.currentTimeMillis() - millis);
//endregion
// region iterator
millis = System.currentTimeMillis();
for (Iterator<Integer> iterator = intsIterator.iterator(); iterator.hasNext(); )
if (iterator.next() % 2 == 0) iterator.remove();
System.out.println(System.currentTimeMillis() - millis);
//endregion
Встроенная система ACL CakePHP действительно мощна, но плохо зарегистрированная с точки зрения деталей фактической реализации. Система, которую мы использовали с некоторым успехом во многих находящихся в CakePHP проектах, следующие.
Это - модификация некоторых систем доступа уровня группы, которые были зарегистрированы в другом месте . Цели нашей системы состоят в том, чтобы иметь простую систему, где пользователи авторизовываются на уровне группы, но они могут иметь определенные дополнительные права на объектах, которые были созданы ими, или на основе в расчете на пользователя. Мы хотели избежать необходимости создавать определенную запись для каждого пользователя (или, больше специально для каждого ARO) в aros_acos
таблица.
у Нас есть таблица Users и таблица Roles.
Пользователи
user_id, user_name, role_id
Роли
id, role_name
Создают дерево ARO для каждой роли (у нас обычно есть 4 роли - Лишенный полномочий Гость (идентификатор 1), Авторизованный пользователь (идентификатор 2), Модератор сайта (идентификатор 3) и Администратор (идентификатор 4)):
cake acl create aro / Role.1
cake acl create aro 1 Role.2 ... etc ...
После этого необходимо использовать SQL или phpMyAdmin или подобный для добавления псевдонимов для всех них, поскольку инструмент командной строки пирога не делает этого. Мы используем 'Роль - {идентификатор}' и 'Пользователя - {идентификатор}' для всех наших.
Мы тогда создаем КОРНЕВОЙ ACO -
cake acl create aco / 'ROOT'
и затем создаем ACOS для всех контроллеров под этим КОРНЕВЫМ:
cake acl create aco 'ROOT' 'MyController' ... etc ...
До сих пор настолько нормальный. Мы добавляем дополнительное поле в aros_acos таблице, названной _editown
, который мы можем использовать в качестве дополнительного действия в actionMap компонента ACL.
CREATE TABLE IF NOT EXISTS `aros_acos` (
`id` int(11) NOT NULL auto_increment,
`aro_id` int(11) default NULL,
`aco_id` int(11) default NULL,
`_create` int(11) NOT NULL default '0',
`_read` int(11) NOT NULL default '0',
`_update` int(11) NOT NULL default '0',
`_delete` int(11) NOT NULL default '0',
`_editown` int(11) NOT NULL default '0',
PRIMARY KEY (`id`),
KEY `acl` (`aro_id`,`aco_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Мы можем тогда установить Подлинный компонент для использования метода 'свернувшегося молока', который проверяет требуемый контроллер/действие против AclComponent:: проверьте (). В app_controller у нас есть что-то вроде:
private function setupAuth() {
if(isset($this->Auth)) {
....
$this->Auth->authorize = 'crud';
$this->Auth->actionMap = array( 'index' => 'read',
'add' => 'create',
'edit' => 'update'
'editMine' => 'editown',
'view' => 'read'
... etc ...
);
... etc ...
}
}
Снова, это - довольно стандартный материал CakePHP. У нас тогда есть checkAccess метод в AppController, который добавляет в материале уровня группы, чтобы проверить, проверить ли группу ARO или пользователь ARO для доступа:
private function checkAccess() {
if(!$user = $this->Auth->user()) {
$role_alias = 'Role-1';
$user_alias = null;
} else {
$role_alias = 'Role-' . $user['User']['role_id'];
$user_alias = 'User-' . $user['User']['id'];
}
// do we have an aro for this user?
if($user_alias && ($user_aro = $this->User->Aro->findByAlias($user_alias))) {
$aro_alias = $user_alias;
} else {
$aro_alias = $role_alias;
}
if ('editown' == $this->Auth->actionMap[$this->action]) {
if($this->Acl->check($aro_alias, $this->name, 'editown') and $this->isMine()) {
$this->Auth->allow();
} else {
$this->Auth->authorize = 'controller';
$this->Auth->deny('*');
}
} else {
// check this user-level aro for access
if($this->Acl->check($aro_alias, $this->name, $this->Auth->actionMap[$this->action])) {
$this->Auth->allow();
} else {
$this->Auth->authorize = 'controller';
$this->Auth->deny('*');
}
}
}
setupAuth()
и checkAccess()
методы называют в AppController
beforeFilter(
), обратный вызов. Существует isMine
метод в AppControler также (см. ниже), который просто проверяет, что user_id требуемого объекта совпадает с в настоящее время аутентифицируемым пользователем. Я пропустил это для ясности.
Это - действительно все, которое существует к нему. Можно тогда позволить / запрещают особого доступа групп к определенному acos -
cake acl grant 'Role-2' 'MyController' 'read'
cake acl grant 'Role-2' 'MyController' 'editown'
cake acl deny 'Role-2' 'MyController' 'update'
cake acl deny 'Role-2' 'MyController' 'delete'
я уверен, что Вы получаете изображение.
Так или иначе, путь этого ответа дольше, чем я предназначил его, чтобы быть, и это, вероятно, не делает рядом ни с каким смыслом, но я надеюсь, что это - некоторая справка к Вам...
- редактирование -
Согласно просьбе, вот отредактированный (просто для ясности - существует много материала в нашем шаблонном коде, это бессмысленно здесь) isMine()
метод, который мы имеем в нашем AppController. Я удалил много материала проверки ошибок также, но это - сущность его:
function isMine($model=null, $id=null, $usermodel='User', $foreignkey='user_id') {
if(empty($model)) {
// default model is first item in $this->uses array
$model = $this->uses[0];
}
if(empty($id)) {
if(!empty($this->passedArgs['id'])) {
$id = $this->passedArgs['id'];
} elseif(!empty($this->passedArgs[0])) {
$id = $this->passedArgs[0];
}
}
if(is_array($id)) {
foreach($id as $i) {
if(!$this->_isMine($model, $i, $usermodel, $foreignkey)) {
return false;
}
}
return true;
}
return $this->_isMine($model, $id, $usermodel, $foreignkey);
}
function _isMine($model, $id, $usermodel='User', $foreignkey='user_id') {
$user = Configure::read('curr.loggedinuser'); // this is set in the UsersController on successful login
if(isset($this->$model)) {
$model = $this->$model;
} else {
$model = ClassRegistry::init($model);
}
//read model
if(!($record = $model->read(null, $id))) {
return false;
}
//get foreign key
if($usermodel == $model->alias) {
if($record[$model->alias][$model->primaryKey] == $user['User']['id']) {
return true;
}
} elseif($record[$model->alias][$foreignkey] == $user['User']['id']) {
return true;
}
return false;
}