第七章 集合
7.1 Java集合概述
7.2 HashSet
Collection接口 : 有很多方法
↑ (继承)
set接口
↑ (实现)
HashSet类
1. HashSet实现的方法
import java.util.HashSet;
import java.util.Set;
public class Test2 {
public static void main(String[] args) {
Set set = new HashSet();
set.add(1);//添加元素
set.add("a");
System.out.println(set);
set.remove(1);//移除元素
System.out.println(set);
set.contains("a");//判断是否包含元素
System.out.println(set.contains("a"));
set.clear();//清空集合
System.out.println(set);
}
}
import java.util.HashSet;
import java.util.Set;
public class Test2 {
public static void main(String[] args) {
Set set = new HashSet();
//如何遍历
set.add("a");
set.add("b");
set.add("c");
set.add("d");
System.out.println(set);
//使用迭代器遍历集合
Iterator it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
//for each迭代集合(推荐使用)
for (Object obj : set) {
//意思是把set的每一个值取出来,赋值给obj,直到循环结束==set的所有值
System.out.println(obj);
}
System.out.println(set.size());//获取集合的元素个数
}
}
运行结果1:
运行结果2
2.hashCode()方法
HashSet集合判断两个元素的标准:两个对象通过equals()方法比较相等,并且两个对象的hashCode()方法返回值也相等
如果两个对象通过equals()方法返回ture,这两个对象的hashCode值也应该相同。
3.泛型
如果想要让集合只能存同样类型的对象,就要使用泛型
Set<Object> set = new HashSet<Object>();
//等价于 Set set = new HashSet();
//String类型的泛型
Set<String> set1 = new HashSet<String>();
set1.add("sss");
7.3TreeSet
package 第七章;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
public class Test {
public static void main(String[] args) {
Set<Integer> set = new TreeSet<Integer>();
//TreeSet自然排序
set.add(5);
set.add(2);
set.add(4);
set.add(3);
System.out.println(set);
set.remove(5);
set.contains(3);
// set.clear();//清空集合
//用迭代器遍历集合
Iterator<Integer> it = set.iterator();
while(it.hasNext()) {
System.out.println(it.next());
//for each 迭代集合
for(Integer i : set ) {
System.out.println(i);
}
}
}
}
必须放入同样类的对象。(默认会进行排序)否则可能会发生类型转换异常。我们可以使用发逆行类进行限制
7.4 List与ArrayList
package 第七章;
import java.util.ArrayList;
import java.util.List;
public class Test1 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("b");//第一个,索引下标0
list.add("d");//索引下标1
list.add("c");//索引下标2
list.add("a");//索引下标3
list.add("d");//允许使用重复元素
System.out.println(list);
System.out.println(list.get(2));//通过索引来访问指定位置的集合元素
list.add(1,"f");//在指定索引下标的位置插入数据
System.out.println(list);
System.out.println(list.indexOf("d"));//获取指定元素在集合中第一次出现的索引下标
System.out.println(list.lastIndexOf("d"));//获取指定元素在集合中最后一次出现的索引下标
list.remove(2);//根据指定的索引下标移除元素
System.out.println(list);
list.set(1, "ff");//根据指定的索引下标修改元素
System.out.println(list);
//根据索引下标的起始位置截取一段元素形成一个新的集合
List<String> sublist = list.subList(2, 4);
System.out.println(sublist);
System.out.println(list.size());//集合的长度
}
}
7.5 Map
package 第七章;
import java.security.KeyStore.Entry;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Test2 {
public static void main(String[] args) {
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("b", 1);//添加数据
map.put("c", 2);
map.put("a", 2);
map.put("e", 1);
System.out.println(map);
System.out.println(map.get("b"));//根据key取值
map.remove("c");//根据key一处键值对
System.out.println(map);
System.out.println(map.size());//map集合的长度
System.out.println(map.containsKey("a"));//判断当前的map集合是否包含指定的key
System.out.println(map.containsValue(10));//判断当前的map集合是否包含指定的value
Set<String> keys = map.keySet();//获取map集合的key的集合
map.values();//获取集合的所有value值
//遍历map集合,通过map.keySet();
for(String key : keys) {
System.out.println("key:" + key + ",value:" + map.get(key));
//通过map.entrySet();
Set<java.util.Map.Entry<String, Integer>> entrys = map.entrySet();
for(java.util.Map.Entry<String, Integer> en : entrys) {
System.out.println("key: " + en.getKey() + ",value: " + en.getValue());
}
}
}
}
7.6 工具类Collections
package 第七章;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class Test3 {
public static void main(String[] args) {
List<String> list = new ArrayList<String>();
list.add("b");
list.add("cd");
list.add("ca");
list.add("a");
list.add("1");
System.out.println(list);
Collections.reverse(list);//反转List中元素的顺序
System.out.println(list);
Collections.shuffle(list);//对List集合元素进行随机排序
System.out.println(list);
Collections.sort(list);//list集合字典升序排序
System.out.println(list);
Collections.swap(list, 0, 4);//将指定list集合中的i处与j处元素进行交换
System.out.println(list);
//返回最大最小值
System.out.println(Collections.max(list));
System.out.println(Collections.min(list));
//new Student类
Student s1 = new Student(14,"张三");
Student s2 = new Student(15,"李四");
Student s3 = new Student(11,"王五");
Student s4 = new Student(13,"周六");
List<Student> stus = new ArrayList<Student>();
stus.add(s1);
stus.add(s2);
stus.add(s3);
stus.add(s4);
for(Student stu : stus) {
System.out.println(stu.name + "," + stu.age);
}
Collections.sort(stus, new Student());
System.out.println("====================");
for(Student stu : stus) {
System.out.println(stu.name + "," + stu.age);
}
}
}
class Student implements Comparator<Student>{
int age;
String name;
public Student(int age, String name) {
this.age = age;
this.name = name;
}
public Student() {//无参构造器
}
@Override
public int compare(Student o1, Student o2) {//根据年龄升序排列对象
if(o1.age > o2.age) {
return 1;
}else if (o1.age < o2.age) {
return -1;
}else {
return 0;
}
}
}
第八章 泛型
8.1 为什么使用泛型
Java中的泛型,只在编译阶段有效。在编译过程中,正确检验泛型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。也就是说,泛型信息不会进入到运行时阶段。
8.2 泛型类
对象实例化时不指定泛型,默认为Object
泛型不同的引用不能相互赋值
class Generic<T>{
private T key;
public void setKey(T key){
this.key = key;
}
public T getKey(){
return key;
}
//在new Generic对象中指定的泛型类型String
Generic<String> g1 = new Generic<String>();
g1.setKey("abc");
Generic<String> g2 = new Generic<String>();
g1.setKey(11);
Generic g3 = new Generic();//不指定泛型,相当于指定一个Object类型
g3.setKey(11);
g3.setKey("abc");
g3.setKey(ture);
}
8.3泛型接口
//定义一个泛型接口
interface Generator<T>{
T next();
}
package 第八章;
public class Test1 {
public static void main(String[] args) {
B1<String> b1 = new B1<String>();
B2 b2 = new B2();
}
}
/**
* 为传入泛型实参时,与泛型类的定义相同,在声明类的时候,须将泛型的声明也一起加到类中
* @author 13088
*
* @param <T>
*/
//定义一个接口
interface IB<T>{
T test(T t);
}
class B1<T> implements IB<T>{
@Override
public T test(T t) {
return t;
}
}
/**
* 如果实现接口时指定接口的泛型的躯体数据类型
* 这个类实现接口所有方法的位置都要泛型替换实际的数据类型
* @author 13088
*
*/
class B2 implements IB<String>{
@Override
public String test(String t) {
return null;
}
}
8.4 泛型方法
方法也可以被泛型化,不管此时定义在其中的类是不是泛型化的。在泛型方法中可以定义泛型参数,此时,参数类型就是传入数据的类型。
//泛型方法的格式
public class DAO[
public<e> void show (E e){
System.out.println(e.toString());
}
public<T> T show1(T t){
return t;
}
]
静态方法无法访问类上定义的泛型,如果静态方法操作的引用数据不确定的时候,必须要将泛型定义在方法上
如果在类中定义使用泛型的静态方法,需要添加额外的泛型声明,即是静态方法要使用泛型类中已经声明过的泛型也不可以
8.5 通配符
不确定集合中的元素具体的数据类型,使用?表示所有类型
public bpid test(List<?> list){
System.out.println(list);
}
通配符
<? extends Preson> (无穷小,Person]
只允许泛型为Person及Person子类的引用调用
<? super Person> [Person,无穷大)
执行运行泛型为Person及Perosn的父类的引用调用
<? extends Comparable>
只允许方法为实现Comparable接口的实现类的引用调用