[英]How to create a base class that works with two different objects?
I have two classes, PersonAdapter and AnimalAdapter . 我有两个类, PersonAdapter和AnimalAdapter 。
Both classes are almost identical so I'm trying to reduce as much boiler plate code as possible. 这两个类几乎是相同的,因此我正在尝试减少尽可能多的样板代码。
PersonAdapter extends from RecyclerView.Adapter . PersonAdapter从RecyclerView.Adapter扩展。
AnimalAdapter extends from RecyclerView.Adapter . AnimalAdapter从RecyclerView.Adapter扩展。 Both classes implements the Filterable interface.
这两个类都实现了Filterable接口。
PersonAdapter defines an inner class PersonFilter extending from Filter . PersonAdapter定义了从Filter扩展的内部类PersonFilter 。
AnimalAdapter defines an inner class AnimalFilter extending from Filter . AnimalAdapter定义了从Filter扩展的内部类AnimalFilter 。
I would like to replace PersonFilter and AnimalFilter with some kind of generic class, but I don't know how since these are the differences between both classes: 我想用某种通用类替换PersonFilter和AnimalFilter ,但是我不知道如何,因为这是两个类之间的区别:
PersonFilter
- works with a List<Person>
- uses Person#getName() to make a string comparison
AnimalFilter
- works with a List<Animal>
- uses Animal#getType() to make a string comparison
Please take a quick look at both classes: 请快速浏览以下两个类别:
PersonAdapter PersonAdapter
public class PersonAdapter extends RecyclerView.Adapter<PersonViewHolder> implements Filterable {
private List<Person> persons;
private PersonFilter personFilter;
public PersonAdapter(List<Person> persons) {
this.persons = persons;
}
...
@Override
public Filter getFilter() {
if(personFilter == null)
personFilter = new PersonFilter(this, persons);
return personFilter;
}
public static class PersonFilter extends Filter {
private final PersonAdapter adapter;
private final List<Person> originalList;
private final List<Person> filteredList;
private PersonFilter(PersonAdapter adapter, List<Person> originalList) {
super();
this.adapter = adapter;
this.originalList = new LinkedList<>(originalList);
this.filteredList = new ArrayList<>();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
filteredList.clear();
final FilterResults results = new FilterResults();
if (constraint.length() == 0) {
filteredList.addAll(originalList);
} else {
final String filterPattern = constraint.toString().toLowerCase().trim();
for (final Person person : originalList) {
if (person.getName().toLowerCase().contains(filterPattern.toLowerCase())) {
filteredList.add(person);
}
}
}
results.values = filteredList;
results.count = filteredList.size();
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.persons.clear();
adapter.persons.addAll((ArrayList<Person>) results.values);
adapter.notifyDataSetChanged();
}
}
}
AnimalAdapter AnimalAdapter
public class AnimalAdapter extends RecyclerView.Adapter<AnimalViewHolder> implements Filterable {
private List<Animal> animals;
private AnimalFilter animalFilter;
public AnimalAdapter(List<Animal> animals) {
this.animals = animals;
}
...
public static class AnimalFilter extends Filter {
private final AnimalAdapter adapter;
private final List<Animal> originalList;
private final List<Animal> filteredList;
private AnimalFilter(AnimalAdapter adapter, List<Animal> originalList) {
super();
this.adapter = adapter;
this.originalList = new LinkedList<>(originalList);
this.filteredList = new ArrayList<>();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
filteredList.clear();
final FilterResults results = new FilterResults();
if (constraint.length() == 0) {
filteredList.addAll(originalList);
} else {
final String filterPattern = constraint.toString().toLowerCase().trim();
for (final Animal animal : originalList) {
if (animal.getType().toLowerCase().contains(filterPattern.toLowerCase())) {
filteredList.add(animal);
}
}
}
results.values = filteredList;
results.count = filteredList.size();
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.animals.clear();
adapter.animals.addAll((ArrayList<Animal>) results.values);
adapter.notifyDataSetChanged();
}
}
}
How should I create a generic subclass of Filter that works both with Animal and Person objects and can be used by PersonAdapter and AnimalAdapter? 我应该如何创建既可以与Animal对象又可以与Animal对象一起使用并且可以被PersonAdapter和AnimalAdapter使用的Filter的通用子类?
Here is a filter that uses generics and a predicate to pull out the two filters from the question. 这是一个使用泛型和谓词的过滤器,从问题中拉出两个过滤器。 The code could be reduced further by using a method similar to Guava Iterable.filter() .
通过使用类似于Guava Iterable.filter()的方法,可以进一步减少代码。
MyAdapterInterface will need to be an interface or shared parent class for the adapters that shares all of the adapter methods that this filter needs to call. MyAdapterInterface将需要是适配器的接口或共享父类,这些适配器共享此过滤器需要调用的所有适配器方法。
public class MyFilter<A extends MyAdapterInterface,T> extends Filter {
private final A adapter;
private final Predicate<T> comparator; // Java 8 class - can easily be created by hand if you are using pre Java 8
// see https://docs.oracle.com/javase/8/docs/api/java/util/function/Predicate.html
private final List<T> originalList;
private final List<T> filteredList;
private MyFilter(A adapter, List<T> originalList, Predicate<T> predicate) {
super();
this.adapter = adapter;
this.comparator = comparator;
this.originalList = new LinkedList<>(originalList);
this.filteredList = new ArrayList<>();
}
@Override
protected FilterResults performFiltering(CharSequence constraint) {
filteredList.clear();
final FilterResults results = new FilterResults();
if (constraint.length() == 0) {
filteredList.addAll(originalList);
} else {
final String filterPattern = constraint.toString().toLowerCase().trim();
for (final T animal : originalList) {
if (predicate.test(animal)) {
filteredList.add(animal);
}
}
}
results.values = filteredList;
results.count = filteredList.size();
return results;
}
@Override
protected void publishResults(CharSequence constraint, FilterResults results) {
adapter.clearResults(); // method to be added to MyAdapterInterface
adapter.addResults(results.values); // method to be added to MyAdapterInterface
adapter.notifyDataSetChanged();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.