黑马程序员---集合-泛型、增强for、Set集合
来源:互联网 发布:互联主机销售系统源码 编辑:程序博客网 时间:2024/06/03 08:57
——Java培训、Android培训、iOS培训、.Net培训、期待与您交流! ——-
一、泛型
集合就像仓库,可以装任何的引用类型;因为它的add()方法接收的是Object类型的。对于集合类,看似功能比较强大,可以添加任何类型的引用。但取出的时候,也比较费事,我们以后使用集合类,经常是向集合中添加一种类型的引用;
在这个时候,Java为我们提供了一种语法功能:可以将一个集合,在定义时,同时定义这个集合中只能存放什么类型的元素。这种功能就叫:泛型;
例如:我们需要定义一个只存储”字符串”的集合:
ArrayList<String> list = new ArrayList<String>(); 或 ArrayList<String> list = new ArrayList<>();(经常使用这种形式) 或 ArrayList<String> list = new ArrayList();
这里看个程序,使用泛型来存储字符串
import java.util.ArrayList;public class Demo { public static void main(String[] args) { //1.定义一个只能存储字符串的集合 ArrayList<String> strList = new ArrayList(); //2.填充元素 strList.add("aaa"); strList.add("bbb"); strList.add("ccc"); //strList.add(10);//编译错误,不能存储非String类型的数据。 //3.遍历 for(int i = 0;i < strList.size() ; i++){ String s = strList.get(i);//取出时,不需要再强转了,直接接收就可以 System.out.println(s); } }}
上面的程序使用泛型后,就不用担心存入的不是规定元素类型,这样使用泛型会给程序员带来几点好处,即:
A:把运行时期的问题提前到了编译期间
B:避免了强制类型转换
C:优化了程序设计,解决了黄色警告线
二、增强for循环
增强for循环又叫foreach循环,它的格式为:
for(数据类型 变量名:集合对象名/数组名){
//语句体
}
使用增强for循环的时候需要注意:
1.增强for不使用循环变量;
2.根据自己的需要,如果需要使用循环变量,那么就使用普通的for循环;如果不需要循环变量,只是简单的遍历一下集合或数组,那么使用增强for的语法会简洁许多。
3.增强for类似于迭代器,通过它对集合进行遍历时,仍然不能使用集合对象对集合内部进行修改,否则将抛出:并发修改异常:java.util.ConcurrentModificationException
import java.util.ArrayList;public class ForeachDemo { public static void main(String[] args) { ArrayList<String> strList = new ArrayList<>(); strList.add("aaa"); strList.add("bbb"); strList.add("ccc"); //之前遍历使用普通for for(int i = 0;i < strList.size() ; i++){ String s = strList.get(i); System.out.println(s); } System.out.println("********增强for循环*******"); //增强for for(String s : strList){ System.out.println(s); } System.out.println("*******普通for循环遍历数组********"); int[] intArray = {432,4,24,32,54,36,54,7,65,64,4}; for(int i = 0;i < intArray.length ; i++){ System.out.println(intArray[i]); } System.out.println("*******增强for循环遍历数组*************"); for(int n : intArray){ System.out.println(n); } }}
普通for循环和增强for循环的效果是一样的,增强for循环的代码看山去简洁,易懂,没有冗余。但是如果要使用循环变量,那就只能用普通for循环了。
三、Set集合的特点
Set接口和List接口都是Collection接口的子类接口,List接口的特点是存储元素可以重复,是有序的。但是Set接口中的元素恰恰相反,即存储的元素没有重复的,是无序的。
下面的程序就证明了这两个特点:
import java.util.HashSet;import java.util.Set;public class Demo { public static void main(String[] args) { //1.实例化一个集合 Set<String> strSet = new HashSet<>(); //2.填充集合 strSet.add("aaa"); strSet.add("bbb"); strSet.add("ccc"); strSet.add("ddd"); //尝试存储重复元素: strSet.add("aaa"); strSet.add("bbb"); //再添加一个新元素 strSet.add("eee"); //3.遍历集合 Object[] objArray = strSet.toArray(); for(Object o : objArray){ System.out.println(o);//取出时,跟存入的顺序是不一致的 } }}
这段程序输出的结果是:
从程序的输出结果就可以看出Set结合的两个特点。
四、HashSet集合存储自定义对象
上面说到的不能存储重复元素,里面的机制是依靠equals()方法和hashCode()方法来实现的,所以为了保证元素的唯一性,需要重写hashCode()方法和equals()方法。这里我们用HashSet结合存储自定义对象Student,来看看怎么实现存储不重复的元素。
先看Student类的代码
public class Student { private String name; private int age; public Student(String name, int age) { super(); 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 "Student [name=" + name + ", age=" + age + "]"; } //重写了hashCode方法 public int hashCode(){ return 0; } //重写了equals方法 @Override public boolean equals(Object o){ if(obj == null){ return false; } if(!(obj instanceof Student)){ return false; } Student stu = (Student)obj; return this.name.equals(stu.getName()) && this.age == stu.getAge(); }}
再看看测试类的代码
import java.util.HashSet;public class Demo { public static void main(String[] args) { //1.实例化一个HashSet HashSet<Student> stuSet = new HashSet<>(); //2.填充集合 stuSet.add(new Student("张三",20)); stuSet.add(new Student("李四",22)); stuSet.add(new Student("王五",24)); stuSet.add(new Student("赵六",26)); //存储重复元素; stuSet.add(new Student("赵六",26));//在重写hashCode和equals()方法后,不能存入了 //3.遍历 for(Student stu : stuSet){ System.out.println(stu); } }}
打印的结果是:
五、LinkedHashSet类
哈希表保证元素的唯一性,链表保证元素的有序(取出时和存入的书序是一样的)。
import java.util.LinkedHashSet;public class Demo { public static void main(String[] args) { //1.实例化一个集合 LinkedHashSet<String> strSet = new LinkedHashSet<>(); //2.填充集合 strSet.add("aaa"); strSet.add("bbb"); strSet.add("ccc"); strSet.add("ddd"); //3.遍历 for(String s : strSet){ System.out.println(s); } }}
六、TreeSet
这个集合内部使用树的数据结构实现的,并且默认会对存入的元素进行比较并排序,这种排序有两种方式,是自然排序和比较器排序。
下面的例子就是这个特点:
import java.util.TreeSet;public class Demo { public static void main(String[] args) { //1.实例化一个TreeSet TreeSet<Integer> set = new TreeSet<>(); //2.填充集合 set.add(88);//先隐式装箱。Set中存储的是Integer类型 set.add(20); set.add(5); set.add(75); set.add(60); set.add(50); set.add(60); set.add(290); //3.打印 for(int n : set){ System.out.println(n); } System.out.println("*****字符串*********"); TreeSet<String> strSet = new TreeSet<>(); strSet.add("b"); strSet.add("d"); strSet.add("a"); strSet.add("c"); strSet.add("f"); strSet.add("e"); for(String s : strSet){ System.out.println(s); } }}
程序运行的结果是:
上面的程序存入的元素都是有比较功能的,如果存储自定义对象的数据了,那TreeSet就不会比较了,程序就会抛出错误,导致程序不能正常运行。
解决的办法有两个:
(1):实现Comparable接口,重写compareTo()方法。这个就是自然排序
(2):给出一个比较器,即实现Comparator接口,重写compareTo()方法。这个就是比较器排序
下面举个存储Student类型的数据的例子
Student类的程序:
public class Student implements Comparable { private String name; private int age; public Student(String name, int age) { super(); 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 "Student [name=" + name + ", age=" + age + "]"; } @Override public int compareTo(Object o) { Student stu = (Student)o; int n = this.name.compareTo(stu.getName()); int n2 = (n == 0 ? this.age - stu.age : n);//如果name相同,再比较年龄 return n2; }}
再看测试类中的代码
import java.util.TreeMap;import java.util.TreeSet;public class Demo { public static void main(String[] args) { TreeSet<Student> stuSet = new TreeSet<>(); stuSet.add(new Student("zhangsan",20)); stuSet.add(new Student("lisi",22)); stuSet.add(new Student("wangwu",24)); stuSet.add(new Student("zhaoliu",26)); stuSet.add(new Student("lisi",32)); TreeMap m; for(Student stu : stuSet){ System.out.println(stu); } }}
程序运行的结果是:
从结果就可以看出,程序只要重写了compareTo()方法,就可以按照重写的规则排序存入的元素。
注意:存入的元素的比较排序默认是基于Unicode编码的,对中文是不支持的。
- 黑马程序员---集合-泛型、增强for、Set集合
- 黑马程序员——集合——Set集合,增强for循环,数据结构,泛型,Collections集合工具类
- 黑马程序员-------Set集合
- 黑马程序员-------Set集合
- 黑马程序员--Set集合
- 黑马程序员 泛型、Set集合类和Map集合类
- 黑马程序员:集合框架Set
- 黑马程序员--java集合Set
- 黑马程序员-集合(Set)
- 黑马程序员-----------------集合框架-Set
- 黑马程序员:集合框架Set
- 黑马程序员----List,Set集合
- 黑马程序员:集合框架Set
- 黑马程序员-----List,Set集合
- 黑马程序员------------List,Set集合
- 黑马程序员-----List,Set集合
- 黑马程序员-----List,Set集合
- 黑马程序员-----List,Set集合
- L1范式和L2范式
- 名词从句的作用
- #298 (div.2) A. Exam
- Unity教程之手把手教你Animator状态机如何切换状态
- hiho第一周——最长回文子串
- 黑马程序员---集合-泛型、增强for、Set集合
- VTR-to-Bitstream 2 FPGA Architecture File(.xml)
- Uva - 1588 - Kickdown
- vs2010 将某一个类添加到一个名字空间中 vs2010创建名字空间及其使用
- IOS开发系列--Objective-C之类和对象
- C++获取系统时间
- time,gettimeofday,clock_gettime,_ftime
- 中东历史
- wishlist