¿Qué tal esto? :
package test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
public class CustomArrayBuilder extends ArrayList<Custom> {
Map<String, Integer> namesMap = new HashMap<String, Integer>();
public CustomArrayBuilder(Collection<? extends Custom> c) {
super(c);
this.prepareAddAll(c);
}
public int getDifferentNamesAmount() {
return this.namesMap.size();
}
public int getNameAmount(String name) {
Integer integer = this.namesMap.get(name);
return (integer != null) ? integer : 0;
}
/**
* {@inheritDoc}
*/
@Override
public Custom set(int index, Custom element) {
Custom custom = super.set(index, element);
prepareSet(custom, element);
return custom;
}
/**
* {@inheritDoc}
*/
@Override
public boolean add(Custom e) {
this.prepareAdd(e);
return super.add(e);
}
/**
* {@inheritDoc}
*/
@Override
public void add(int index, Custom element) {
this.prepareAdd(element);
super.add(index, element);
}
/**
* {@inheritDoc}
*/
@Override
public Custom remove(int index) {
Custom custom = super.remove(index);
this.prepareRemove(custom);
return custom;
}
/**
* {@inheritDoc}
*/
@Override
public void clear() {
super.clear();
this.namesMap.clear();
}
/**
* {@inheritDoc}
*/
@Override
public boolean addAll(Collection<? extends Custom> c) {
this.prepareAddAll(c);
return super.addAll(c);
}
/**
* {@inheritDoc}
*/
@Override
public boolean addAll(int index, Collection<? extends Custom> c) {
this.prepareAddAll(c);
return super.addAll(index, c);
}
/**
* {@inheritDoc}
*/
@Override
public boolean remove(Object o) {
if (super.remove(o)) {
this.prepareRemove((Custom) o);
return true;
} else {
return false;
}
}
private void prepareSet(Custom oldCustom, Custom newCustom) {
if (oldCustom != null && !oldCustom.name.equals(newCustom.name)) {
this.prepareRemove(oldCustom);
this.prepareAdd(newCustom);
}
}
private void prepareAdd(Custom custom) {
if (custom != null) {
Integer integer = this.namesMap.get(custom.name);
this.namesMap.put(custom.name, (integer != null) ? integer + 1 : 1);
}
}
private void prepareAddAll(Collection<? extends Custom> c) {
for (Custom custom : c) {
this.prepareAdd(custom);
}
}
private void prepareRemove(Custom custom) {
if (custom != null) {
Integer integer = this.namesMap.get(custom.name);
this.namesMap.put(custom.name, (integer != null && integer > 0) ? integer - 1 : 0);
}
}
}
Uso:
package test;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) {
List<Custom> list = new ArrayList<Custom>() {{
add(new Custom("A"));
add(new Custom("B"));
add(new Custom("C"));
add(new Custom("A"));
add(new Custom("A"));
add(new Custom("B"));
}};
CustomArrayBuilder customs = new CustomArrayBuilder(list);
Custom custom = new Custom("B");
customs.add(custom);
customs.add(custom);
customs.remove(custom);
customs.remove(custom);
customs.remove(custom);
System.out.println("A: " + customs.getNameAmount("A"));
System.out.println("B: " + customs.getNameAmount("B"));
System.out.println("C: " + customs.getNameAmount("C"));
System.out.println("Z: " + customs.getNameAmount("Z"));
System.out.println("Total different names: " + customs.getDifferentNamesAmount());
}
}
Salida:
A: 3
B: 2
C: 1
Z: 0
Total different names: 3
Podría ser muy útil cuando se utiliza con frecuencia sus operaciones de recuento. Nota: No debe cambiar el nombre del objeto personalizado, debe ser definitiva:
package test;
class Custom {
public int id;
final public String name;
public Custom(String name) {
this.name = name;
}
}
O usted tiene que hacer algo con la lista también, cuando se cambia el nombre de un objeto personalizado en la lista.
No hay 'Linq' para Java, aunque hay esto ... http://stackoverflow.com/questions/346721/linq-for-java-tool – xandercoded