Android 使用泛型方法保存List集合并使用反射排序

最近一直使用数据库保存数据,想到了List集合保存对象更方便,便将方法已泛型的方式实现,便于通用



注 要使用到文件存储,所以在别忘记加文件权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />



首先我们创建名为BookInfo 、PeopleInfo的javabean文件

//由于要使用对象流,所以类需要实现序列化接口
public class BookInfo implements Serializable {
    private String bookName ;
    private String author ;
    private float price ;

    public BookInfo() {
    }

    public BookInfo(String bookName, String author, float price) {
        this.bookName = bookName;
        this.author = author;
        this.price = price;
    }

    public String getBookName() { return bookName;  }

    public void setBookName(String bookName) {this.bookName = bookName; }

    public String getAuthor() { return author; }

    public void setAuthor(String author) {this.author = author;}

    public float getPrice() { return price; }

    public void setPrice(float price) { this.price = price;  }

    @Override
    public String toString() {
        return "{" + "bookName='" + bookName + '\'' + ", author='" + author + '\'' + ", price=" + price + '}';
    }
}
public class PeopleInfo implements Serializable {

    private String name ;
    private int age ;

    public PeopleInfo(String name, int age) { this.name = name; this.age = age; }

    public String getName() {return name;}

    public void setName(String name) {this.name = name;}

    public int getAge() {return age;}

    public void setAge(int age) {this.age = age;}

    @Override
    public String toString() {
        return "PeopleInfo{" + "name='" + name + '\'' + ", age=" + age + '}';
    }
}



创建DataUtils的工具类(主)

public class DataUtils {

    // 文件写入List集合对象
    public static  void writeInfo(Context context , List info , String fileName)  {

        //创建文件流和对象流
        FileOutputStream fos  = null ;
        ObjectOutputStream oos = null ;
        try {
            fos=context.openFileOutput(fileName , Context.MODE_PRIVATE);
            oos = new ObjectOutputStream(fos) ;
            // 写入对象
            oos.writeObject(info);
        } catch (IOException e) {
            e.printStackTrace();
        }

        // 关闭对象流
        try {
            if(oos != null) {
                oos.close();
            } else if(fos!=null) {
                fos.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 文件读取List集合对象
    public static  List  readInfo(Context context , String fileName) {
        List info  = new ArrayList<>() ;

        //创建文件流和对象流
        FileInputStream fis  = null ;
        ObjectInputStream ois = null ;
        try {
            fis= context.openFileInput(fileName) ;
            ois = new ObjectInputStream(fis) ;
            //读取文件中的对象
            info = (List) ois.readObject() ;
        } catch (IOException | ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        // 关闭对象流
        try {
            if(ois != null) {
                ois.close();
            } else if(fis!=null) {
                fis.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return info;
    }

    // 由于泛型需要具体类型 所以说不能使用泛型
    //methodName:代表获取JavaBean中方法名 , state : 0升序 1降序
    //注 如果List集合存储对象有其他类型,可以instanceof继续判断扩充实现
    //通过方法名去寻找是对象中是否有这个方法,这种字符串反射调用方法方式相比类对象引用跟灵活
    public static  void sortInfo(List list , final String methodName , final Integer state)   {
        //原样输出
        if(methodName == null || state == null){
            return ;
        }

        //判断方法是否存在
        if(!methodExis(list.get(0) , methodName)) {
            System.out.println("方法不存在") ;
            return ;
        }

        Collections.sort(list, new Comparator() {
            @Override
            public int compare(T o1, T o2) {
                Object ob1 = getData(o1 , methodName);;
                Object ob2 = getData(o2 , methodName);

                //判断对象是否为空 是变不做判断
                if(ob1 == null || ob2 == null) {
                    return 0 ;
                }

                if(ob1 instanceof Integer || ob1 instanceof Float || ob1 instanceof Double) {

                    //避免三个类型转化出错,统一转化为Double类型进行比较
                    if (Double.parseDouble(ob1+"") >= Double.parseDouble(ob2+"") ) {
                        return state==0? 1:state ==1? -1:0 ;
                    }
                    return state==0? -1:state ==1? 1:0 ;


                }   else if(ob1 instanceof String) {

                    Collator collator = Collator.getInstance(Locale.CHINA) ;
                    if ( collator.compare(((String)ob1) , (String)ob2) >0  ) {
                        return state==0 ? 1 : state ==1? -1:0 ;
                    }
                    return state==0? -1 : state ==1? 1:0 ;
                }
                return 0;
            }
        });

    }

    // 判断方法名是否存在
    // T:对象,methodName:代表获取JavaBean中方法名
    public static  boolean methodExis(T info , String methodName) {
        Class cls = (Class) info.getClass() ;
        Method[] method = cls.getDeclaredMethods() ;
        for(int i=0 ; iif(methodName.equals(method[i].getName())) {
                return true ;
            }
        }
        return false ;
    }


    // 获取方法反射调用返回方法的值
    public static Object getData(T info , String st)  {
        Class cls = (Class) info.getClass();
        Method f = null;
        Object obj = null;
        try {
            f = cls.getDeclaredMethod(st, new Class[0]);
            obj = f.invoke(info);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return obj ;
    }
}

主方法调用

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //创建BookInfo的集合对象
        List  infos = new ArrayList<>() ;
        infos.add(new BookInfo("第一行代码" , "郭霖" ,40.2f)) ;
        infos.add(new BookInfo("Android开发艺术" , "任玉刚" ,50.1f)) ;
        infos.add(new BookInfo("疯狂Android讲义" , "李刚" ,45.4f)) ;
        //创建PeopleInfo的集合对象
        List listP = new ArrayList<>() ;
        listP.add(new PeopleInfo("张三" , 21)) ;
        listP.add(new PeopleInfo("李四" , 19)) ;

        //写入对象
        DataUtils.writeInfo(this , infos , "book");
        DataUtils.writeInfo(this , listP , "people");

        //读取对象
        List copy = DataUtils.readInfo(this , "book") ;
        List copy1 = DataUtils.readInfo(this , "people") ;

        //BookInfo集合排序
        paint("默认输出" , copy , null , 0);
        paint("价格升序排列打印" , copy , "getPrice" , 0);
        paint("价格降序排列打印" , copy , "getPrice" , 1);
        paint("人名升序排列打印" , copy , "getAuthor" , 0);
        //PeopleInfo获取集合排序
        paint("人名升序排列打印" , copy1 , "getName" , 0);

    }

    public void paint( String logN, List list , String MethodName , int state){
        Log.d("BookInfo" , logN) ;
        DataUtils.sortInfo(list ,MethodName ,  state);
        for(int i=0 ; i"BookInfo" , list.get(i).toString() ) ;
        }
    }
}

    public void paint( String logN, List list , String MethodName , int state){
        Log.d("BookInfo" , logN) ;
        DataUtils.sortInfo(list ,MethodName ,  state);
        for(int i=0 ; i"BookInfo" , list.get(i).toString() ) ;
        }
    }
}

打印信息 ,成功实现

Android 使用泛型方法保存List集合并使用反射排序_第1张图片

注:由于只做了list方法没优化,所以只能保存List< JavaBean序列化对象> 比如 List< List< info>> 、Map<> 等便无法保存 , 当然也可以自己去实现

你可能感兴趣的:(数据保存)