美文网首页
Java入门系列08 -- 泛型,集合

Java入门系列08 -- 泛型,集合

作者: YanZi_33 | 来源:发表于2021-11-12 22:18 被阅读0次

    泛型

    • 从Java5开始,引入泛型技术;
    • 泛型:将类型变为参数,提高代码的复用率;
    • 建议使用的类型参数名称有:
      • T:Type
      • E:Element
      • K:Key
      • N:Number
      • V:Value
      • S,U,V:2nd,3rd,4th types
    泛型类型
    • 泛型类型:使用了泛型的类或者接口;
    public class Student<T> {
        private T scores;
    
        public Student(T scores) {
            this.scores = scores;
        }
    }
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //分数参数 可以传任意类型
            //调用的时候 必须指定一个具体类型
            Student<String> student1 = new Student<String>("A");
            Student<Double> student2 = new Student<Double>(100.0);
            Student<Integer> student3 = new Student<Integer>(90);
            //右侧的泛型类型可以省略
            Student<Integer> student3 = new Student<>(90);
        }
    }
    
    • 定义泛型之后,在调用时必须指定一种特定的类型;
    泛型类型的继承
    • 案例代码:
    public class Box<E>{
        private E element;
    
        public E getElement() {
            return element;
        }
    
        public void setElement(E element) {
            this.element = element;
        }
    }
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //Box<String>与Box<Object> 之间没有继承关系
            Box<String> box1 = new Box<>();
            Box<Object> box2 = new Box<>();
            //报错
            //box2 = box1;
    
            box2.setElement(new Object());
            String str = box1.getElement();
        }
    }
    
    • Box<String>与Box<Object> 之间没有继承关系;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Iterable<String> iterable = null;
            Collection<String> collection = null;
            List<String> list = null;
            ArrayList<String> arrayList = null;
    
            iterable = collection;
            collection = list;
            list = arrayList;
         }
    }
    
    • Iterable<String>Collection<String>List<String>ArrayList<String>四种之间存在继承关系,如下所示:
    image.png
    • 所以 使用父类指针指向子类对象,不会出现错误;
    import java.util.List;
    
    public interface YYList<E,T> extends List<E> {
        void  setNo(T no);
    }
    
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            List<String> list = null;
            YYList<String,Integer> yyList1 = null;
            YYList<String,Double> yyList2 = null;
            YYList<String,String> yyList3 = null;
    
            list = yyList1;
            list = yyList2;
            list = yyList3;
         }
    }
    
    • 继承关系图下所示:
    image.png
    • 自定义接口YYList<E,T>继承自Java类List<E>,虽然实例化时,T的类型不同,它们之间依然有继承关系,所以用父类指针指向子类对象,不会报错;
    原始类型
    • 原始类型:没有传递具体的类型 给泛型 的类型参数;
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //Box 称为Box<E> 的原始类型
            //使用原始类型 会出现警告,需要我们在使用泛型时 要指定一个类型
            Box rawBox = new Box();
    
            Box<String> boxStr = new Box<>();
            Box<Double> boxDou = new Box<>();
    
            rawBox = boxStr;
            rawBox = boxDou;
    
            boxStr = rawBox;
            boxDou = rawBox;
         }
    }
    
    • Box 称为Box<E>原始类型
    • Box<Object>是非原始类型;
    • 当使用了原始类型时,编译器会给出rawtypes警告,可以使用@SuppressWarnings进行消除;
    • 非原始类型 赋值给 原始类型时,编译器没有任何警告和错误;
    • 将原始类型赋值给非原始类型时,编译器会给出unchecked警告,可以使用@SuppressWarnings进行消除;
    泛型方法
    • 泛型方法:使用了泛型的方法(实例方法,静态方法,构造方法);
    public class Student<N,S> {
        private N no;
        private S scores;
    
        public Student(N no,S scores) {
            this.no = no;
            this.scores = scores;
        }
    
        public N getNo() {
            return no;
        }
    
        public void setNo(N no) {
            this.no = no;
        }
    
        public S getScores() {
            return scores;
        }
    
        public void setScores(S scores) {
            this.scores = scores;
        }
    }
    
    public class MainActivity extends AppCompatActivity {
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Student<String,Integer> student = new Student<>("1",100);
            set(student,"2",99);
    
            //出现报错
            Student<Integer,Double> student1 = new Student<>(5,77.5);
            //set(student1,66,44.5);
            sett(student1,5,89.5);
         }
    
         public static void set(Student<String,Integer> student,String no,Integer scores) {
            student.setNo(no);
            student.setScores(scores);
         }
    
         //属于泛型方法
         public static <T1,T2> void sett(Student<T1,T2> student,T1 no,T2 scores) {
             student.setNo(no);
             student.setScores(scores);
         }
    }
    
    • 首先set方法,其参数的类型是写死的,只能接受student实例对象,若又要接受student1实例对象,出现类型冲突就会报错,可使用泛型方法settpublic static <T1,T2> void sett(Student<T1,T2> student,T1 no,T2 scores)
    public class Box<E>{
        private E element;
    
        public Box() {}
        public Box(E element) {
            this.element = element;
        }
    
        public E getElement() {
            return element;
        }
    
        public void setElement(E element) {
            this.element = element;
        }
    }
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            List<Box<Integer>> boxes = new ArrayList<>();
            addBox(11,boxes);
            addBox(22,boxes);
            addBox(33,boxes);
    
         }
    
         public static <T> void addBox(T element, List<Box<T>> boxes) {
            Box<T> box = new Box<>(element);
            boxes.add(box);
         }
    }
    
    泛型方法 -- 构造方法
    public class YYPerson<T> {
    
        private T age;
        public <E> YYPerson(E name,T age) {
    
        }
    }
    
    public class MainActivity extends AppCompatActivity {
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            YYPerson<Integer> person1 = new YYPerson("yanzi",10);
            YYPerson<Double> person2 = new YYPerson("23.9",33.6);
            YYPerson<String> person3 = new YYPerson<String>(11,"23");
         }
    }
    
    限制类型参数
    • 可以通过extends对类型参数增加一些限制条件,比如<T extends A>;
    • extends后面可以跟上类名,接口名,代表T必须是A类型,或者继承,实现A;
    public class Person<T extends Number>{
        private T age;
    
        public T getAge() {
            return age;
        }
    
        public void setAge(T age) throws  Exception{
            if (age == null) {
                System.out.println("age不合理");
                //抛出异常
                throw new Exception("age必须>0");
            } else {
                this.age = age;
            }
        }
    }
    
    • <T extends Number>:泛型T 只能是数字类型;
    public class Person implements Comparable<Person>{
        private int age;
    
        public int getAge() {
            return age;
        }
    
        public Person(int age) {
            this.age = age;
        }
    
        public void setAge(int age) throws  Exception{
            if (age <= 0) {
                System.out.println("age不合理");
                //抛出异常
                throw new Exception("age必须>0");
            } else {
                this.age = age;
            }
        }
    
        @Override
        public int compareTo(Person o) {
            if (o == null) return 1;
            return age - o.age;
        }
    }
    
    import com.example.java_test.java.cls.Person;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Integer[] arr = {11,33,21,45,77,32};
            System.out.println("Main" + getMax(arr));
    
            Person[] ps = {new Person(11),new Person(22),new Person(66)};
            System.out.println("Main" + getMax(ps));
        }
    
        public static <T extends Comparable<T>> T getMax(T[] array) {
            if (array.length == 0 || array == null) return null;
            T max = array[0];
            for (int i = 1; i < array.length; i++) {
                if (array[i].compareTo(max) <= 0) continue;
                max = array[i];
            }
            return max;
        }
    }
    
    • public static <T extends Comparable<T>> T getMax(T[] array):泛型方法,传入的数组元素 必须限制可以支持比较大小,即
    • 传入的Person对象数组,必须支持大小上的比较,需实现Comparable接口;
    import com.example.java_test.java.cls.Person;
    import java.util.Arrays;
    import java.util.Comparator;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Person[] ps = {new Person(11),new Person(22),new Person(66)};
            Arrays.sort(ps, new Comparator<Person>() {
                @Override
                public int compare(Person o1, Person o2) {
                    return o1.getAge() - o2.getAge();
                }
            });
        }
    }
    
    • Comparator:是比较器;
    public class Student<T extends Comparable<T>> implements Comparable<Student<T>>{
        private T scores;
    
        public Student(T scores) {
            this.scores = scores;
        }
    
        public T getScores() {
            return scores;
        }
    
        public void setScores(T scores) {
            this.scores = scores;
        }
    
        @Override
        public int compareTo(Student<T> o) {
            if (o == null) return 1;
            if (score != null) return scores.compareTo(o.scores);
            return o.scores != null ? -1 : 0;
        }
    }
    
    import com.example.java_test.java.cls.Student;
    
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Student[] ss = {new Student(11),new Student(22),new Student(66)};
            System.out.println("Main" + getMax(ss));
    
        }
    
        public static <T extends Comparable<T>> T getMax(T[] array) {
            if (array.length == 0 || array == null) return null;
            T max = array[0];
            for (int i = 1; i < array.length; i++) {
                if (array[i].compareTo(max) <= 0) continue;
                max = array[i];
            }
            return max;
        }
    }
    
    • public class Student<T extends Comparable<T>> implements Comparable<Student<T>>:Student支持可比较性,内部属性scores也支持可比较性;
    通配符
    • 在泛型中,问号(?)被称为是通配符;
    • 通常用作变量类型,返回值类型的类型参数;
    • 不能用作泛型方法调用,泛型类型实例化,泛型类型定义的类型参数;
    通配符 -- 上界
    • 通过extends设置类型参数的上界;
    • 类型参数必须是当前类型或者是当前类型的子类型;
    public class Box<T> {
    
    }
    
    import com.example.java_test.java.cls.Box;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Box<Integer> box1 = new Box<>();
            Box<Double> box2 = new Box<>();
            Box<Object> box3 = new Box<>();
    
            //通配符 泛型中仅支持数字 可以是Integet,Double等等
            Box<? extends Number> box4 = null;
    
            showBox1(box1);
            showBox1(box2);
            showBox1(box3);
            showBox1(box4);
    
            showBox2(box1);
            showBox2(box2);
            showBox2(box3); //报错
            showBox2(box4);
    
            showBox3(box1);
            showBox3(box2);
            showBox3(box3); //报错
            showBox3(box4);
        }
    
        public static <T> void showBox1(Box<T> box) {
    
        }
    
        public static <T extends Number> void showBox2(Box<T> box) {
    
        }
    
        public static  void showBox3(Box<? extends Number>  box) {
    
        }
    }
    
    通配符 -- 下界
    • 可以通过super设置类型参数的下界;
    • 类型参数必须是当前类型或者当前类型的父类型
    import com.example.java_test.java.cls.Box;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
         
            Box<Integer> b1 = new Box<>();
            Box<Number> b2 = new Box<>();
            
            testLower(b1);
            testLower(b2);
        }
        
        public static void testLower(Box<? super Integer> box) {} 
    }
    
    通配符 -- 无限制
    import com.example.java_test.java.cls.Box;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            Box<Integer> b1 = new Box<>();
            Box<Number> b2 = new Box<>();
            Box<String> b3 = new Box<>();
    
            test(b1);
            test(b2);
            test(b3);
        }
    
        public static void test(Box<?> box) {}
    }
    
    • public static void test(Box<?> box):类型没有限制
    通配符 -- 注意点
    • 编译器在解析List<E>.set(int index,E element)时,无法确定E的真实类型,会报错;
    import java.util.List;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    
        }
    
        public static void test1(List<Integer> list) {
            Integer obj = list.get(0);
            list.set(0,obj);
            list.set(0,list.get(0));
        }
    
        public static void test2(List<?> list) {
            Object obj = list.get(0);
            list.set(0,obj); //报错
            list.set(0,list.get(0));
        }
    
        public static <T> void test(List<T> list) {
            T obj = list.get(0);
            list.set(0,obj); //报错
            list.set(0,list.get(0));
        }
    }
    
    泛型的使用限制
    • 基本类型不能作为类型参数;
    import java.util.HashMap;
    import java.util.Map;
    
    public class MainActivity extends AppCompatActivity {
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //报错
            Map<int ,char> map = new HashMap<>();
            Map<Integer, Character> map1 = new HashMap<>();
        }
    }
    
    • 不能创建类型参数的实例;
    • 不能定义类型为类型参数的静态变量,也不能用在静态方法上;
    public class Box<E> {
         private static E value; //报错
    }
    
    • 类型参数不能与instanceof一起使用;
    ArrayList<Integer> list = new ArrayList<>();
    if (list instaceof ArrayList<Integer>) {
    
    }
    
    • 不能创建带有类型参数的数组;
    Box<Integer>[] boxs = new Box<Integer>[4]; //报错
    Box<Integer>[] boxs = new Box[4]; //ok
    
    • 不能构成重载;
    void test(Box<Integer> box) {
    
    }
    
    void test(Box<String> box) {
    
    }
    
    • 不能定义泛型的异常类;
    public class MyException<T> extends Exception {
    
    }
    
    • catch的异常类型不能用类型参数;
    public staic <T extends Exception> void test(Box<T> box) {
        try {
    
        } catch (T e) { //报错
    
        }
    }
    

    集合

    • java.util包中有个集合框架(Collections Framework),提供了一大堆常用的数据结构;
      • ArrayList,LinkedList,Queue,Stack,HashSet,HashMap等;
    • 数据结构是计算机存储,组织数据的方式,常见的数据结构有:线性结构,树形结构,图形结构;
    集合框架预览
    image.png
    • List的特点:
      • 可以存储重复的元素;
      • 可以通过索引访问元素;
      • 有记录元素的添加顺序;
    • Set的特点:
      • 不可以存储重复的元素;
      • 不可以通过索引访问元素;
      • 不记录元素的添加顺序;
    数组的局限性
    public class MainActivity extends AppCompatActivity {
        
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            int[] array = new int[4];
            array[0] = 0;
            array[1] = 1;
            array[2] = 2;
            array[3] = 3;
         }
    }
    
    • 数组无法动态扩容,上述array只能存储不超过4个元素;
    • 操作元素的过程不够面向对象;
    • java.util.ArrayList是Java中动态数组,可以动态扩容,且封装了各种使用的数组操作;
    ArrayList的基本使用
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ArrayList list = new ArrayList();
            //添加元素
            list.add(11);
            list.add(false);
            list.add(null);
            list.add(3.14);
            list.add(0,"yanzi");
            list.add('8');
    
            //获取元素索引
            System.out.println("Main" + list.indexOf(null));
            System.out.println("Main" + list.size());
            System.out.println("Main" + list);
    
            //移除
            list.remove(8);
            list.remove(1);
            //是否包含
            boolean isContains = list.contains(11);
         }
    }
    
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ArrayList list1 = new ArrayList();
            //添加元素
            list1.add(11);
            list1.add(22);
            list1.add(33);
            list1.add(44);
            
            ArrayList<Integer> list2 = new ArrayList<>();
            list2.add(22);
            list2.add(44);
            
            //从list1中 删除list2 中元素以外的所有元素
            list1.retainAll(list2);
            
            //list1 [22,44]
         }
    }
    
    • retainAll:从list1中 删除list2 中元素以外的所有元素;
    import java.util.ArrayList;
    
    public class MainActivity extends AppCompatActivity {
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ArrayList<Integer> list1 = new ArrayList();
            //添加元素
            list1.add(11);
            list1.add(22);
            list1.add(33);
    
            //实现将动态数组 --> 普通数组
            //arr是一个存储Object的数组
            Object[] arr = list1.toArray();
            for (Object obj : arr) {
                System.out.println("Main:" + obj.getClass());
            }
            //这么写 可以转成 存储Integer的数组
            Integer[] arr2 = list1.toArray(new Integer[0]);
         }
    }
    
    • Integer[] arr2 = list1.toArray(new Integer[0]):将动态数组 转成 普通数组;
    ArrayList的遍历
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.function.Consumer;
    
    public class MainActivity extends AppCompatActivity {
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ArrayList<Integer> list1 = new ArrayList();
            //添加元素
            list1.add(11);
            list1.add(22);
            list1.add(33);
            //经典
            int size = list1.size();
            for (int i = 0; i < size; i++) {
                System.out.println("Main:" + list1.get(i));
            }
    
            //迭代器
            Iterator<Integer> iterator = list1.iterator();
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
            }
            
            //for-each 下面的底层实现 本质就是上面的迭代器 实现方式 
            for (Integer i: list1) {
                System.out.println(i);
            }
            
            //四面四种写法等价 
            //函数式接口
            list1.forEach(new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) {
                    System.out.println(integer);
                }
            });
            
            list1.forEach((i) -> {
                System.out.println(i);
            });
    
            list1.forEach((i) -> System.out.println(i));
            list1.forEach(System.out::println);
         }
    }
    
    • 遍历 for -each格式如下:
    for (元素类型 变量名 : 数组/Iterable) {
    
    }
    
    • 实现了Iterable接口的对象,都可以使用for -each格式遍历元素,例如List,Set等等;
    • Iterable在使用for -each格式遍历元素,本质是使用了Iterator对象;
    自定义Iterable,Iterator
    import androidx.annotation.NonNull;
    import java.util.Iterator;
    
    public class ClassRoom implements Iterable<String>{
    
        private  String[] students;
    
        public ClassRoom(String... students) {
            this.students = students;
        }
    
        public String[] getStudents() {
            return students;
        }
    
        public void setStudents(String[] students) {
            this.students = students;
        }
    
        @NonNull
        @Override
        public Iterator<String> iterator() {
            return new ClassRoomIterator();
        }
    
        //内部类
        private class ClassRoomIterator implements Iterator<String> {
    
            private int cursor;
    
            @Override
            public boolean hasNext() {
                return cursor < students.length;
            }
    
            @Override
            public String next() {
                return students[cursor++];
            }
        }
    }
    
    • ClassRoom 实现 Iterable接口,然后提供一个自定义的遍历器ClassRoomIterator
    ArrayList的扩容原理
    遍历的注意事项
    • 若希望在遍历元素的同时删除元素;
      • 请使用Iterator进行遍历;
      • 然后使用Iterator的remove方法进行删除元素;
    • 使用迭代器,forEach在遍历集合元素的时候,若使用了集合自带的方法修改了集合的长度(例如add,remove等方法)
      • 那么可能会抛出java.util.ConcurrentModificationException异常
    import java.util.ArrayList;
    import java.util.Iterator;
    
    public class MainActivity extends AppCompatActivity {
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ArrayList<Integer> list = new ArrayList<>();
            list.add(11);
            list.add(22);
            list.add(33);
            list.add(44);
            list.add(55);
            list.add(66);
    
            //一边遍历 -- 一边删除 会出现数组越界
    //        int size = list.size();
    //        for (int i = 0; i < size; i++) {
    //            list.remove(i);
    //        }
    
            //出现异常 ConcurrentModificationException
    //        for (Integer e : list) {
    //            list.remove(e);
    //        }
    
            //本质同上
    //        Iterator<Integer> iterator = list.iterator();
    //        while (iterator.hasNext()) {
    //            list.remove(iterator.next());
    //        }
    
            //依然报错
    //        list.forEach((object) -> {
    //            list.remove(object);
    //        });
    
            //正确写法
            //游标
            Iterator<Integer> iterator = list.iterator();
            while (iterator.hasNext()) {
                iterator.next();
                iterator.remove();
            }
         }
    }
    
    • 迭代器,forEach在遍历数组元素时,内部会检测modCount是否发生变化,若发生变化就会抛出异常,而使用集合自身修改集合长度的方法就会改变modCount值;
    ListIterator
    • ListIterator继承自Iterator,在Iterator的基础上增加了一些功能;
    import java.util.ArrayList;
    import java.util.ListIterator;
    
    public class MainActivity extends AppCompatActivity {
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            ArrayList<Integer> list = new ArrayList<>();
            list.add(11);
            list.add(22);
            list.add(33);
    
            ListIterator<Integer> iterator = list.listIterator();
            //从前往后遍历
            while (iterator.hasNext()) {
                System.out.println(iterator.next());
            }
    
            //从后往前遍历
            while (iterator.hasPrevious()) {
                System.out.println(iterator.previous());
            }
    
            while (iterator.hasNext()) {
                //让数组中每个元素 + 55
                iterator.set(iterator.next() + 55);
            }
    
            //[100,11,200,100,22,200,100,33,200]
            while (iterator.hasNext()) {
                //让数组中每个元素 前后 分别插入 两个元素 100与200
                iterator.add(100);
                System.out.println(iterator.next());
                iterator.add(200);
            }
         }
    }
    
    函数式接口
    • Supplier函数式接口
    import java.util.function.Supplier;
    
    public class MainActivity extends AppCompatActivity {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //makeString()一定会调用
            String str = getFirstNotEmptyString("124",makeString());
        }
    
        public static String makeString() {
            return "sds";
        }
    
        public static String getFirstNotEmptyString(String s1,String s2) {
            if (s1 != null && s1.length() > 0) return s1;
            if (s2 != null && s2.length() > 0) return s2;
            return null;
        }
    }
    
    • makeString()方法一定会被调用,现作如下优化;
    import java.util.function.Supplier;
    
    public class MainActivity extends AppCompatActivity {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
    
            String sttr = getFirstNotEmptyString("123", new Supplier<String>() {
                @Override
                public String get() {
                    return makeString();
                }
            });
        }
    
        public static String makeString() {
            return "sds";
        }
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        public static String getFirstNotEmptyString(String s1, Supplier<String> supplier) {
            if (s1 != null && s1.length() > 0) return s1;
            String s2 = supplier.get(); 
            if (s2 != null && s2.length() > 0) return s2;
            return null;
        }
    }
    
    • makeString()方法,只有在s1为空的情况下才会调用,由于Supplier是函数式接口,再优化如下:
    import java.util.function.Supplier;
    
    public class MainActivity extends AppCompatActivity {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            //函数式接口
            String sttr = getFirstNotEmptyString("123", () -> makeString());
        }
    
        public static String makeString() {
            return "sds";
        }
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        public static String getFirstNotEmptyString(String s1, Supplier<String> supplier) {
            if (s1 != null && s1.length() > 0) return s1;
            String s2 = supplier.get();
            if (s2 != null && s2.length() > 0) return s2;
            return null;
        }
    }
    
    • Consumer函数式接口
    import java.util.function.Consumer;
    
    public class MainActivity extends AppCompatActivity {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            int[] nums = {11,22,33};
            foreach(nums, new Consumer<Integer>() {
                @Override
                public void accept(Integer integer) {
                    System.out.println("Main:" + (integer + 100));
                }
            });
    
            //等价写法
            foreach(nums,(num) ->  System.out.println("Main:" + (num + 100)));
        }
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        public static void foreach(int[] nums, Consumer<Integer> consumer) {
            if (nums == null) return;
            for (Integer num : nums) {
                consumer.accept(num);
            }
        }
    }
    
    import java.util.function.Consumer;
    
    public class MainActivity extends AppCompatActivity {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            
            int[] nums = {11,22,33,44,566,778,8};
            foreach(nums,(n) -> {
                
            },(n) -> {
                
            });
        }
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        public static void foreach(int[] nums, Consumer<Integer> c1,Consumer<Integer> c2) {
            if (nums == null || c1 == null || c2 == null) return;
            for (Integer num : nums) {
                c1.andThen(c2).accept(num);
            }
        }
    }
    
    • Predicate函数式接口
    import java.util.function.Predicate;
    
    public class MainActivity extends AppCompatActivity {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            int[] nums = {11,22,33,44,566,778,8,66};
            //过滤奇数
            String str = join(nums,(n) -> (n & 1) == 0);
            System.out.println("Main:" + str);
    
            //过滤偶数
            String str3 = join3(nums,(n) -> (n & 1) == 0);
            System.out.println("Main:" + str);
    
            //两个条件同时满足 and
            String str1 = join2(nums,(n) -> (n & 1) == 0,(n) -> (n % 3 == 0));
            System.out.println("Main:" + str1);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        public static String join(int[] nums, Predicate<Integer> p) {
            if (nums == null || p == null) return null;
            StringBuilder sb = new StringBuilder();
            for (int n: nums) {
                if (p.test(n)) {
                    sb.append(n).append("_");
                }
            }
            sb.deleteCharAt(sb.length() - 1);
            return sb.toString();
        }
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        public static String join2(int[] nums, Predicate<Integer> p1,Predicate<Integer> p2) {
            if (nums == null || p1 == null) return null;
            StringBuilder sb = new StringBuilder();
            for (int n: nums) {
                if (p1.and(p2).test(n)) {
                    sb.append(n).append("_");
                }
            }
            sb.deleteCharAt(sb.length() - 1);
            return sb.toString();
        }
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        public static String join3(int[] nums, Predicate<Integer> p) {
            if (nums == null || p == null) return null;
            StringBuilder sb = new StringBuilder();
            for (int n: nums) {
                if (p.negate().test(n)) {
                    sb.append(n).append("_");
                }
            }
            sb.deleteCharAt(sb.length() - 1);
            return sb.toString();
        }
    }
    
    • Function函数式接口
    import java.util.function.Function;
    
    public class MainActivity extends AppCompatActivity {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            String[] strs = {"123","34","43"};
            int result = sum(strs,(str) -> Integer.valueOf(str));
    
            //先String转Integer 然后Integer % 10
            int result1 = sum1(strs,(str) -> Integer.valueOf(str),(i) -> i % 10);
        }
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        public static int sum(String[] strings, Function<String,Integer> f) {
            if (strings == null || f == null) return 0;
            int result = 0;
            for (String str : strings) {
                result += f.apply(str);
            }
            return result;
        }
    
        @RequiresApi(api = Build.VERSION_CODES.N)
        public static int sum1(String[] strings, Function<String,Integer> f1,Function<Integer,Integer> f2) {
            if (strings == null || f1 == null) return 0;
            int result = 0;
            for (String str : strings) {
                result += f1.andThen(f2).apply(str);
            }
            return result;
        }
    }
    
    LinkedList
    HashSet
    • 元素无序的;
    • 元素不可重复;
    LinkedHashSet
    • 在HashSet的基础上,记录了元素的添加顺序;
    TreeSet
    • TreeSet要求元素必须具备可比较性,默认按照从小到大的顺序遍历元素;
    • 可自定义比较器,按照特定的规则进行排序;
    HashMap (开发中常用的字典)
    • HashMap存储的是键值对,也可称字典;
    • 不可以存储重复的key,可以存储重复的value;
    • 不可以通过索引访问元素;
    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Set;
    
    public class MainActivity extends AppCompatActivity {
        @RequiresApi(api = Build.VERSION_CODES.N)
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            HashMap<String,String> map = new HashMap<>();
            //添加键值对
            map.put("name","yanzi");
            map.put("age","33");
            map.put("height","175");
            map.put("weight","120");
    
            //移除键值对
            map.remove("height");
    
            //遍历键值对
            Set<Map.Entry<String,String>> entries = map.entrySet();
            for (Map.Entry<String,String> entry : entries) {
                System.out.println(entry.getKey() + "=" + entry.getValue());
            }
    
            map.forEach((key,value) -> {
                System.out.println(key + "=" + value);
            });
    
            Collection<String> values = map.values();
            for (String value: values) {
                System.out.println(value);
            }
    
            Set<String> keys = map.keySet();
            for (String key : keys) {
                System.out.println(key + "=" + map.get(key));
            }
        }
    }
    
    LinkedHashMap
    • 在HashMap的基础上,记录了元素的添加顺序;
    TreeMap
    • TreeMap要求元素必须具备可比较性,默认按照从小到大的顺序遍历key;
    Collections
    • java.util.Collections是一个常用的集合工具类,提供了很多实用的静态方法;
    总结:
    • Set的底层是基于Map实现的;

    相关文章

      网友评论

          本文标题:Java入门系列08 -- 泛型,集合

          本文链接:https://www.haomeiwen.com/subject/htbozltx.html