1. 泛型,泛型是jdk1.5中引入的新特性,本质是参数化类型。所以接口中的方法的参数(形参、返回值)不确定时,可以考虑使用泛型接口。
命名规则:
1 public interface Fan<E> { 2 3 public void showinfo(E t); 4 5 }
1 public class Test1 implements Fan<String>{ 2 //实现类能确定泛型接口的类型
3 @Override
4 public void showinfo(String t) { 5 6 } 7 8 }
1.2 泛型的上限和下限
1) 泛型的上限 ArrayList(? extends 类1) list 声明了一个容器,容器中的元素类型一定要继承于 类1 ,我们称这种形式叫做泛型的上限。
1 public class Phone { 2 private String model; 3 private String name; 4 private int signal; 5 public String getName; 6 7 8 public String getModel() { 9 return model; 10 } 11 12 public void setModel(String model) { 13 this.model = model; 14 } 15 16 public String getName() { 17 return name; 18 } 19 20 public void setName(String name) { 21 this.name = name; 22 } 23 24 public int getSignal() { 25 return signal; 26 } 27 28 public void setSignal(int signal) { 29 this.signal = signal; 30 } 31 32 public Phone(String model, String name, int signal) { 33 super(); 34 this.model = model; 35 this.name = name; 36 this.signal = signal; 37 } 38 39 public Phone() { 40 super(); 41 this.signal = 80; 42 } 43 44 public void showInfo(){ 45 System.out.println("这是一台:"+this.getName()); 46 System.out.println("信号强度:"+this.getSignal()); 47 System.out.println("型号是:"+this.getModel()); 48 } 49 50 51 }
1 public class NewMachine extends Phone{ 2 private String inter; 3 4 public String getInter() { 5 return inter; 6 } 7 8 public void setInter(String inter) { 9 this.inter = inter; 10 } 11 12 public NewMachine(String model, String name, int signal, String inter) { 13 super(model, name, signal); 14 this.inter = inter; 15 } 16 17 public NewMachine() { 18 super(); 19 } 20 21 @Override 22 public void showInfo() { 23 super.showInfo(); 24 System.out.println("新功能:"+this.getInter()); 25 } 26 }
1 import java.util.ArrayList; 2 3 public class Test1 { 4 5 public static void print(ArrayList<? extends Phone> list) {//容器中的元素类型一定要继承于Phone类。(泛型的上限) 6 for (Phone phone : list) { 7 phone.showInfo(); 8 } 9 } 10 11 12 public static void main(String[] args) { 13 NewMachine phone1 = new NewMachine("MI", "智能手机", 90, "手游优化"); 14 NewMachine phone2 = new NewMachine("HUAWEI", "智能手机", 90, "手游优化"); 15 NewMachine phone3 = new NewMachine("MEIZU", "智能手机", 90, "手游优化"); 16 17 ArrayList<NewMachine> phones = new ArrayList<NewMachine>(); 18 phones.add(phone1); 19 phones.add(phone2); 20 phones.add(phone3); 21 22 print(phones);//需要声明泛型的上限ArrayList(? extends Pet) list 才能正常使用,不然会出现报错。 23 24 } 25 26 }
2) 同样,泛型的下限 ArrayList(? super 类2) list 声明了一个容器,容器中的元素类型一定是这个 类2 的父类,我们称这种形式叫做泛型的下限。
2. Set接口 和 Set的集合实现类HashSet
1) Set是无序的,用于存储不重复的对象集合。在Set集合中存储的对象中,不存在两个对象equals比较为true的情况。
2) HashSet和TreeSet是Set集合的两个常见的实现类,分别用hash表 和 排序二叉树的方式实现了Set集合。HashSet是使用散列算法实现Set的。
1 import java.util.HashSet; 2 import java.util.Iterator; 3 import java.util.Set; 4 5 public class Test1 { 6 public static void main(String[] args) { 7 Set<Integer> set = new HashSet<Integer>(); 8 9 set.add(10); 10 set.add(13); 11 set.add(55); 12 set.add(10);//与第0位添加的10重复 13 System.out.println(set); //输出[55, 10, 13], Set是无序的,存不重复元素,所以不能添加重复元素。 14 15 Set<String> set2 = new HashSet<String>(); 16 set2.add("lemon"); 17 set2.add("apple"); 18 set2.add("banana"); 19 //Set支持Iterator迭代器遍历和快速遍历 20 for (String item : set2) { 21 System.out.println(item);//输出banana apple lemon 22 } 23 24 //迭代器遍历 25 Iterator<String> it = set2.iterator(); 26 while (it.hasNext()) { 27 String item1 = it.next(); 28 System.out.println(item1);//输出banana apple lemon 29 } 30 31 //优化写法 32 for (Iterator<String> it2 = set2.iterator(); it2.hasNext();) { 33 String item3 = it2.next(); 34 System.out.println(item3);//输出banana apple lemon 35 } 36 } 37 }
3) TreeSet,底层数据结构是 二叉树 。如果添加的元素本身具备了自然顺序的特征,按自然序输出。
1 import java.util.Iterator; 2 3 import java.util.TreeSet; 4 5 public class Test01 { 6 public static void main(String[] args) { 7 TreeSet<Integer> set = new TreeSet<Integer>(); 8 9 set.add(10); 10 set.add(13); 11 set.add(55); 12 set.add(10);// 与第0位添加的10重复 13 System.out.println(set); // 输出[10, 13, 55], Set是无序的,TreeSet的底层数据结构是二叉树,如果元素本身具备了自然顺序的特征,按自然序输出 14 15 TreeSet<String> set2 = new TreeSet<String>(); 16 set2.add("lemon"); 17 set2.add("apple"); 18 set2.add("banana"); 19 // Set支持Iterator迭代器遍历和快速遍历 20 for (String item : set2) { 21 System.out.println(item);// 输出 apple banana lemon ,元素本身具备了自然顺序的特征,按自然序输出 22 } 23 24 // 迭代器遍历 25 Iterator<String> it = set2.iterator(); 26 while (it.hasNext()) { 27 String item1 = it.next(); 28 System.out.println(item1);// 输出 apple banana lemon,元素本身具备了自然顺序的特征,按自然序输出 29 } 30 31 // 优化写法 32 for (Iterator<String> it2 = set2.iterator(); it2.hasNext();) { 33 String item3 = it2.next(); 34 System.out.println(item3);// 输出 apple banana lemon,元素本身具备了自然顺序的特征,按自然序输出 35 } 36 } 37 38 }
4)添加自定义元素,这些元素没有一个自然顺序,就要提供一个当前类的一种比较策略(规则),比较策略(规则)分两种:内部比较策略 和 外部比较策略。
①内部比较策略:要使用 Comparable接口,实现compareTo(T o)方法。
1 public class Phone implements Comparable<Phone> { 2 private String model; 3 private String name; 4 private int signal; 5 6 public String getModel() { 7 return model; 8 } 9 10 public void setModel(String model) { 11 this.model = model; 12 } 13 14 public String getName() { 15 return name; 16 } 17 18 public void setName(String name) { 19 this.name = name; 20 } 21 22 public int getSignal() { 23 return signal; 24 } 25 26 public void setSignal(int signal) { 27 this.signal = signal; 28 } 29 30 public Phone(String model, String name, int signal) { 31 super(); 32 this.model = model; 33 this.name = name; 34 this.signal = signal; 35 } 36 37 public Phone() { 38 super(); 39 40 } 41 42 43 44 @Override 45 public String toString() { 46 return "Phone [model=" + model + ", name=" + name + ", signal=" 47 + signal + "]"; 48 } 49 50 @Override 51 public int compareTo(Phone o) {//多种比较因素 52 if (this.getSignal() < o.getSignal()) { 53 return -1; 54 } else if (this.getSignal() == o.getSignal()) { 55 return this.getName().compareTo(o.getName()); 56 } else { 57 return 1; 58 } 59 60 } 61 62 }
对象实现Comparable并实现compareTo方法时:
1 import java.util.TreeSet; 2 3 public class Test2 { 4 public static void main(String[] args) { 5 TreeSet<Phone> set = new TreeSet<Phone>(); 6 7 Phone p1 = new Phone("9P", "MI", 90); 8 Phone p2 = new Phone("XS MAX", "APPLE", 80); 9 Phone p3 = new Phone("P30", "HUAWEI", 95); 10 Phone p4 = new Phone("N10", "NOTE", 99); 11 12 set.add(p1); 13 set.add(p2); 14 set.add(p3); 15 set.add(p4); 16 17 System.out.println(set); 18 //输出[Phone [model=XS MAX, name=APPLE, signal=80], Phone [model=9P, name=MI, signal=90], Phone [model=P30, name=HUAWEI, signal=95], Phone [model=N10, name=NOTE, signal=99]]
19 } 20 21 }
②外部比较策略:Comparator 位于java.util包中,定义了compare(o1,o2) 用于提供外部比较策略。TreeSet接受一个指定比较策略的构造方法,这些比较策略的实现类必须实现Comparator接口。
1 import java.util.Comparator; 2 import java.util.TreeSet; 3 4 public class Test { 5 public static void main(String[] args) { 6 LenComparator lenComparator = new LenComparator(); 7 8 TreeSet<String> set = new TreeSet<String>(lenComparator); 9 10 set.add("lemon"); 11 set.add("orange"); 12 set.add("apple"); 13 set.add("banana"); 14 System.out.println(set);//输出[lemon, orange] ,apple的字符长度和lemon一样所以不能添加 15 16 } 17 18 } 19 20 21 class LenComparator implements Comparator<String> {//外部比较器,定义字符串长度作为比较 22 23 @Override 24 public int compare(String o1, String o2) { 25 return o1.length() - o2.length(); 26 } 27 }
3. Mapj接口
1)键值对集合或者映射集合,其中的元素(entry)是以键值对(key-value)的形式存在。
2)Map 容器接口中同样提供了增、删、改、查的方式对集合进行操作。
3)Map接口中都是通过key来操作键值对,一般key是已知。通过key获取value。
1 import java.util.HashMap; 2 import java.util.Map; 3 4 public class Test1 { 5 public static void main(String[] args) { 6 7 Map<String, String> map = new HashMap<String, String>(); 8 9 map.put("A", "apple"); 10 map.put("L", "lemon"); 11 map.put("B", "banana"); 12 13 String val = map.get("A"); 14 15 System.out.println(val.toString()); 16 17 System.out.println(map.containsKey("L"));// 查看集合中是否存在 该元素,存在返回true 18 19 System.out.println(map);// 输出{A=apple, B=banana, L=lemon} 键值对集合用大括号括起 20 21 } 22 23 }