泛型
再次强调一下泛型的好处
-
提高代码的重用性
-
防止类型转化异常,提高代码的安全性
< >内常见的如: T 代表一般的任何类。 E 代表 Element 的意思,或者Exception异常的意思。 K 代表 Key 的意思 V 代表 Value 的意思,通常与 K 一起配合使用。 S 代表 Subtype 的意思,
我们一般如何使用泛型类和泛型方法呢?
public class Demo1 { public static void main(String[] args) { MyGeneric<String> myGeneric1 = new MyGeneric<>(); MyGeneric<Integer> myGeneric2 = new MyGeneric<>(); System.out.println(myGeneric1.method("Hello,World!")); System.out.println(myGeneric2.method(20)); /* 这两个都是同一种类的同一种方法,但由于创建对象时<>内的数据类型不同,能传入的参数类型也就不同了,即可以接受多个类型参数,提高代码的重用性 */ } } class MyGeneric<T> { T t; public T method(T t) { System.out.println(t.toString()); return t; } }
测试结果如下:
泛型接口同样也是如此,我们有2种形式来是实现:
// 泛型接口 public interface MyGeneric1<T> { public T method1(T t); }
// 继承泛型接口的泛型类 // 第一种就是在类实现接口时确定接口参数类型 public class MyGeneric<T> implements MyGeneric1<String>{ T t; public T method(T t) { System.out.println(t.toString()); System.out.println("-------------"); return t; } @Override public String method1(String s) { System.out.println(s); return s; } // 此时使用method1这个方法就只能传入String类型的参数了 }
// 第二种 public class MyGeneric<T> implements MyGeneric1<T>{ T t; public T method(T t) { System.out.println(t.toString()); System.out.println("-------------"); return t; } @Override public T method1(T t) { System.out.println("Interface:" + t.toString()); return t; } } //---------------------------------------------------- // 运行 public class Demo1 { public static void main(String[] args) { MyGeneric<String> myGeneric1 = new MyGeneric<>(); MyGeneric<Integer> myGeneric2 = new MyGeneric<>(); System.out.println(myGeneric1.method1("Hello,World!")); System.out.println(myGeneric2.method1(20)); } }
运行结果如下:
这就是泛型的大致内容了,了解了泛型,下面我们就开始学习Collection、List和Set了
Collection、List
首先还是这张图
Collection是List的父接口,由于这2个都是接口,所以要使用它们的方法必须要new一个实现类,比如:
Collection collection = new ArrayList(); List list = new ArrayList();
Collection
Collection中比较常用的方法有:
bollean add(E e)//向集合添加一个元素 bollean addAll(Collection c)//向集合添加一个另一个集合里面的元素 void clear()//清空集合里面的元素 bollean contains(Object o)//判断集合里面是否有o这个元素 bollean contains(Collection c)//判断该集合集合里面是否有c这个集合里面的所有元素 bollean isEmpty()//判断集合是否为空 Iterator<E> iterator()//迭代器 bollean remove(Object o)//删除某个元素 bollean removeAll(Collection c)//删除某个集合里面对应的元素 int size()//显示集合里面元素的个数
因为集合可以包含任意的对象,所以我们可以先定义一个Student来举例:
public class Student { private String name; private int age; public Student(String name,int age) { this.age = age; this.name = name; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
我们直接上代码:
public static void main(String[] args) { Collection collection = new ArrayList(); Student s1 = new Student("李华",15); Student s2 = new Student("小明",14); Student s3 = new Student("红红",15); Student s4 = new Student("王五",16); collection.add(s1); collection.add(s2); collection.add(s3); collection.add(s4); System.out.println(collection.size()); System.out.println(collection.toString()); System.out.println(collection.contains(s1)); System.out.println(collection.contains(new Student("李华",15))); }
结果为:
当我们用System.out.println(collection.contains(new Student("李华",15)));
来判断时会发现给了false,这是因为当你new一个新的对象时系统会自动帮你开辟一个内存出来,所以此“李华”非彼“李华”(当然人可能有重名并重岁的),但是如果我们就认为姓名和年纪一样的人就是一样的人时该怎么办呢?
如何判断我们输入的对象是否为集合中的对象?编译器自有自己的一套标准,即通过重写equals来实现!
public class Student { private String name; private int age; public Student(String name,int age) { this.age = age; this.name = name; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; //这里的等于是用来判断基本数据类型的 if (o == null || getClass() != o.getClass()) return false;//这里判断传入的参数是不是该类的对象 Student student = (Student) o; return age == student.age && Objects.equals(name, student.name); } }
这样得到的结果就还是true啦
remove和contains判断元素是否一样的原理是一样的,这里就不再赘述了,直接上代码和运行结果。
public class Demo1 { public static void main(String[] args) { Collection collection = new ArrayList(); Student s1 = new Student("李华",15); Student s2 = new Student("小明",14); Student s3 = new Student("红红",15); Student s4 = new Student("王五",16); collection.add(s1); collection.add(s2); collection.add(s3); collection.add(s4); System.out.println(collection.size()); System.out.println(collection.toString()); System.out.println(collection.contains(s1)); System.out.println(collection.contains(new Student("李华",15))); collection.remove(new Student("红红",15)); System.out.println(collection.size());// 判断是否删除成功 } }
最后一个重要的内容就是遍历了!
Collection集合的数是无序的,所以相应的,我们只有2种办法来遍历这个集合。
-
增强for循环
-
遍历器遍历
public class Demo1 { public static void main(String[] args) { Collection collection = new ArrayList(); Student s1 = new Student("李华",15); Student s2 = new Student("小明",14); Student s3 = new Student("红红",15); Student s4 = new Student("王五",16); collection.add(s1); collection.add(s2); collection.add(s3); collection.add(s4); for (Object o: collection) { Student s = (Student) o; System.out.println(s.toString()); } System.out.println("-------------------------------");// 分割线 Iterator it = collection.iterator(); while(it.hasNext()) { System.out.println(it.next()); } } }
结果如下:
可以知道,我们这两种方法都可以对collection进行遍历,下面来具体了解一下迭代器
Iterator
其实迭代器常见的只有3个方法
-
Bollean hasNext() //如果迭代具有多个函数,则返回true
-
E next() //返回迭代中的下一个元素
-
default void remove( ) //从底层集合中删除此迭代器返回的最后一个元素
在这里我们用Iterator类来创建一个对象来接收collection.iterator();
List
List相对与collection多了一些方法,而且它本身也是有序的,我们对集合遍历的方法又多了一种
for(int i = 0;i < list.size();i++) {//已经提前创建了对象List list = new ArrayList(); System.out.println(list.get(i)); }
不仅如此,list还允许在集合中按照下表进行某些操作,下面简单地列一些常见的方法。
-
Collection中只有bollean add(E e),而List中还有void add(int index,E element)
-
List中还有了get(int index)方法,这也是List能使用第三种方法来遍历集合的原因!
-
E remove(int index)同上
-
E set(int index,E element)方法可以用指定的元素替换此列表中指定位置的元素
大致的内容就是这样,更详细的内容会在下面的ArrayList和LinkedList讲到,感谢观看!