简体   繁体   English

如何创建可用于两个不同对象的基类?

[英]How to create a base class that works with two different objects?

I have two classes, PersonAdapter and AnimalAdapter . 我有两个类, PersonAdapterAnimalAdapter

Both classes are almost identical so I'm trying to reduce as much boiler plate code as possible. 这两个类几乎是相同的,因此我正在尝试减少尽可能多的样板代码。

PersonAdapter extends from RecyclerView.Adapter . PersonAdapterRecyclerView.Adapter扩展。

AnimalAdapter extends from RecyclerView.Adapter . AnimalAdapterRecyclerView.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: 我想用某种通用类替换PersonFilterAnimalFilter ,但是我不知道如何,因为这是两个类之间的区别:

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.

相关问题 如何创建两个相同但状态不同的对象 - How to create two of the same objects but in different states 如何创建具有列表的类,列表应包含两种不同类型的对象 - how to create class that that has a list in it, and the list should contain two different kind of objects 机器人方法如何访问类中的两个不同对象 - Robot method how to access two different objects in the class 如何匹配来自不同类的两个页面对象文本? - How to match two page objects text from Different Class? 如何使用不同的类对象创建一个类的数组? 爪哇 - how to create an array of one class using a different classes objects? Java 如何在 class 中为两个不同的任务在两个不同的构造函数中使用不同的初始化创建单个 HashMap 成员 - How to create a single HashMap member in a class for two different task with different initialization in two different constructors 在Java中为两个不同的对象创建一个封闭类 - Creating an enclosing class for two different objects in java Singleton类返回两个不同的单例对象 - Singleton class return two different singleton objects 显示一个类的两个对象的不同值 - Show different values two objects of one class 具有两个构造函数的类,将不同的对象作为父项 - Class with two constructors taking different objects as parents
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM