Existe um padrão que ajudará com essa estrutura de dados

5

Estou fazendo um projeto em java. Minha estrutura principal contém 2 listas com elementos do tipo A e o outro tipo B. O próprio B contém uma lista de objetos que podem conter elementos de A.

Deve ser que quando um elemento da lista de A é removido, ele deve ser removido de todos os subelementos da lista B. também se um possível membro da lista A for adicionado a um B, ele também deve ser adicionado a A. E também Eu preciso de alguma maneira para encontrar os objetos pai contendo um A.

Até agora eu tenho uma implementação "funcional" - usando muitos loops. Eu estou pensando - você pode sugerir padrões que me ajudarão nessa tarefa?

mais detalhes.

Acho que meu principal problema é que eu tenho objetos A que têm vários pais. E quando eu adiciono / removo de um dos pais eu preciso ajustar alguns outros pais.

Não posso deixar de acreditar que esse problema já foi resolvido.

para esclarecer: eu tenho um main List<A> , e cada B contém um List<A>

Quando um A é removido da lista principal, ele deve ser removido de todos os B. Mas não quando é removido de um B. É essencial que todos os A usados no aplicativo estejam presentes na lista principal.

    
por bdecaf 18.02.2012 / 11:51
fonte

4 respostas

2

Eu não acho que você precise de nenhum padrão particularmente complexo para isso. Percorrer as estruturas e fazer as mudanças óbvias deve funcionar (supondo que você não tenha problemas de simultaneidade)

Algumas ideias a considerar:

  • Torne os objetos List<A> em HashMap<A, Set<B>> , em que a chave é um objeto do tipo A e o valor é um conjunto de todos os objetos pai-pai.
  • Então você pode encontrar facilmente todos os pais de um dado A, e se você remover uma instância de A, então você pode encontrar rapidamente todos os objetos B dos quais você também precisa remover a instância de A.
  • É claro que você precisará atualizar essa estrutura sempre que adicionar um A a um B, mas essa é apenas uma operação O (1).
  • Os objetos B devem ter uma função remove(A a) que encapsula todo o código necessário para remover uma determinada instância A da estrutura de dados interna. Isso deve chamar recursivamente uma função de remoção semelhante em quaisquer subestruturas.
por 18.02.2012 / 16:20
fonte
3

Você pode fazer isso com referências fracas . Envolva um List<WeakReference<A>> eeo wrapper tem uma referência à estrutura de dados principais (pensando em um conjunto, mas não seguro) que mantém as referências reais para cada A. Quando você exclui de uma estrutura envolvida, remove a referência fraca e exclui da estrutura set, que deve ser a única referência real para cada A. Isso tem alguns problemas com o trabalho com as listas devido a ter eliminado as referências fracas mortas.

    
por 18.02.2012 / 15:41
fonte
0

para algum comentário estranho, não posso adicionar comentários à sua pergunta. Então, vou comentar aqui. Por favor, não vote nisso se você não gostar. Eu não tenho escolha .

Parece que isso é muito semelhante a problemas no banco de dados sql. Por exemplo

create table A
(
    id int not null primary key,
    val varchar(20) not null
);

create table B (
    id int not null primary key,
    val varchar(20) not null
);

create table BA (
    b_id int not null ,
    a_id int not null,
    constraint ba_b_fk foreign key (b_id) references B(id),
    constraint ba_a_fk foreign key (a_id) references A(id) on delete CASCADE  ,
    constraint ba_pk primary key (b_id , a_id)
);

drop table ba;

insert a (id, val) values (1 , 'a1');
insert a (id, val) values (2 , 'a2');
insert a (id, val) values (3 , 'a3');
insert a (id, val) values (4 , 'a4');

insert b (id, val) values (1 , 'b1');
insert b (id, val) values (2 , 'b2');

insert ba (b_id , a_id) values (1 , 2);
insert ba (b_id , a_id) values (1 , 3);

delete a where a.id = 2

select * from ba;
--  only ( 1 , 3) left in ba

Eu não estou familiarizado com java (mas eu trabalho em c #). De qualquer forma, algum pseudo código aqui pode ajudar. Eu fiquei sem tempo para implementá-lo. (por favor note que ATable, BTable são singletons)

class RecA {
    public int id;
    public string val;
    public override bool Equal(object x) { ... }
    public override int GetHashCode() { return ... }
}
class RecB {
    public int id;
    public string b_val;
    public HashSet<A> listA;



}
class ATable extends HashSet<RecA> {

}

class BTable extends HashSet<RecB> {

    public static Dictionary<A, List<B>> dict = new Dictionary<A, List<B>>() ; // to track relationship between BTable and ATable
    public override void Add(RecB) {
    }

    public void addA_to_BTable(RecA) {
        // use the dictionary to track it
    }

    public void delete_A(RecA) {
    }
}
    
por 18.02.2012 / 15:18
fonte
0

Se a sua lista principal contém apenas A's que estão em alguns B's, você pode calcular a lista principal a partir dos B's que você possui. (Mais tarde, você poderá pensar em armazenar em cache a lista principal.)

    
por 18.02.2012 / 15:49
fonte