一.泛型
1.
泛型:标识着集合中存储元素的数据类型
写法:<数据类型(泛型)> 不能放基本数据类型 ,只能他们的包装类 即对象或者引用数据类型。
好处:
1.保证数据的安全性(提示方法中传入的参数类型)。
2.避免进行向下转型(类型转换)。
3.将运行时的错误 转化到编译时报错。
代码实例:
import java.util.ArrayList;
import java.util.ListIterator;
public class Demo01 {
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String[] args) {
//创建一个集合 保存a b c d
//E 泛型 Elemment(元素)
//注意:前后泛型的类型要一直(如果填的话)
//jdk1.7 菱形泛型 后边的泛型可以不填 默认和前面的泛型类型一致
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
//迭代器遍历
//迭代器 泛型 表示 集合中保存元素的类型
ListIterator<String> listIterator = list.listIterator();
while (listIterator.hasNext()) {
String next = listIterator.next();
System.out.println(next);
}
}
2.数组转集合
注意:asList() 该方法 只能转完集合后 ,不能对集合长度进行修改。
注意传入参数的类型
代码例子:
public static void fun5() {
//数组转集合
int[] arr1 = {1, 2, 2, 3, 5};
//是把int数组当做一个元素 放入集合
//系统未进行自动装箱
List<int[]> list = Arrays.asList(arr1);
System.out.println(list);
//如果是Integer 类型数组 ,是对象类型,不需要装箱,可以把元素直接放在集合中
Integer[] arr2 = {1, 2, 2, 3, 5};
List list2 = Arrays.asList(arr2);
System.out.println(list2);
// 创建一个字符串数组 保存三个名字
// 将数组 转成集合
// 添加一个名字
//UnsupportedOperationException 不支持操作 异常
//asList() 该方法意义在于 可使用集合类方法进行修改查找等
String[] arr3 = {"kll1", "kll2", "kll3"};
List<String> list3 = Arrays.asList(arr3);
System.out.println(list3);
System..out.println(list3.contains("kll4"));
}
3.类中带All方法的泛型含义
? extends E 子类 继承 父类
相当于 传入的参数 必须是 父类(E)的子类或本类
可以限定参数类型(向下限定)
addAll方法的代码例子:
import java.util.ArrayList;
import java.util.ListIterator;
public class Kll {
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String[] args) {
//集合存储的类型是人类对象
ArrayList<> list1 = new ArrayList<>();
list1.add(new Person("kll1", 21));
list1.add(new Person("kll2", 25));
ArrayList<Student> list2 = new ArrayList<>();
list1.add(new Student("kll3", 24));
list1.add(new Student("kll4", 23));
//addAll(Collection ? extends E)
// E list1的泛型
// ? list2 的泛型
//且有继承关系
list1.addAll(list2);
System.out.println(list1);
}
}
//人类
public class Person {
private String name;
private int age;
//构造方法
public Person() {
super();
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
//set/get方法
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 "Person [name=" + name + ", age=" + age + "]";
}
}
4.泛型类
4.1泛型类
泛型声明位置:类名<泛型>。
泛型 ,使用占位符(英文字符) ,一般使用大写字母 有意义的。
4.2什么时候 指定泛型的真正类型?
创建对象时 ,会给泛型赋值类型。
4.3一个类中可不可以有多个泛型?
可以。
需要在方法上, 进行泛型的声明。
该泛型 ,会在该方法被调用的时候赋值。
4.4静态方法不能使用 类的泛型
静态方法 ,可以使用新的泛型。
下面是创建创建泛型类代码:
public class Worker<W> {
// 利用泛型声明 成员变量
private W w;
//泛型声明 set/get 方法
public void setW(W w) {
this.w = w;
}
public W getW() {
return this.w;
}
//成员方法
public void fun(W w) {
System.out.println(w);
System.out.println("泛型类方法");
}
//一个类中可不可以有多个泛型? 可以
// 需要在方法上 进行泛型的声明
//该泛型 会在该方法被调用的时候赋值
public<Y> void fun1(Y y) {
System.out.println(y);
System.out.println("调用的泛型方法");
}
//静态方法不能使用 W泛型
//静态方法 可以使用新的泛型
public static<F> void fun2(F f) {
System.out.println(f);
}
}
下面是调用泛型类代码:
public class Demo01 {
@SuppressWarnings({ "unchecked", "rawtypes" })
public static void main(String[] args) {
// 创建集合 保存3学生
// 获取集合中的第0个学生 并打印姓名
ArrayList<Student> list = new ArrayList<>();
list.add(new Student("k1", 26));
list.add(new Student("k2", 22));
list.add(new Student("k3", 21));
//获取集合中的第0个学生的姓名 并打印
String name = list.get(0).getName();
System.out.println(name);
//好处3
//Worker worker = (Worker)list.get(0);
}
}
5.泛型接口
泛型接口代码:
interface InterA<G>{
public abstract void fun1(G g);
}
泛型类型确定 :可以在 ,接口实现类上 确定。
class InterImpl implements InterA<String>{
@Override
public void fun1(String g) {
// TODO Auto-generated method stub
}
}
二.多参数方法
1.多参数方法代码:
//多参数方法 : int ... num
//int ... num 表示可以接收多个int类型值 相当于参数是个数组
public static void print(String str, int ... num) {
// 遍历
for (int i = 0; i < num.length; i++) {
System.out.println(num[i]);
}
}
2.调用方式:
1.传入多个值 ,用逗号隔开。
2.直接传入数组也可以。
注意:如果传入不同类型的多个参数,多参数方法需要放在最后
public static void fun4() {
//调用多参数方法
print("k", 1, 2, 3, 4, 5);
int[] array = {1, 1, 1, 1, 1};
print("l", array);
}
三.集合类工具
1.创建集合,根据年龄降序 排列集合。
使用集合工具类swap()方法 ,可以直接交换位置。省去set方法。
代码案例:
import java.util.ArrayList;
import java.util.Collections;
import java.util.ListIterator;
public class Demo02 {
public static void main(String[] args) {
ArrayList<Student> list1 = new ArrayList<>();
list1.add(new Student("k1", 21));
list1.add(new Student("k2", 24));
list1.add(new Student("k3", 22));
list1.add(new Student("k3", 23));
list1.add(new Student("k3", 20));
list1.add(new Student("k3", 22));
list1.add(new Student("k3", 26));
//按年龄排序
for (int i = 0; i < list1.size() - 1; i++) {
for (int j = 0; j < list1.size() - 1 - i; j++) {
//取出两个学生
Student stu1 = list1.get(j);
Student stu2 = list1.get(j + 1);
//比较年龄
if (stu1.getAge() < stu2.getAge()) {
//交换位置
/*list1.set(j, stu2);
list1.set(j + 1, stu1);*/
//集合工具类 提供的 交换方法
Collections.swap(list1, j, j + 1);
}
}
}
//打印集合
System.out.println(list1);
}
}
四.两种删除方式
第一种:循环删除,代码如下:
public static void fun1(ArrayList<String> list1) {
//循环删除b
for (int i = 0; i < list1.size(); i++) {
String string = list1.get(i);
if ( string.equals("b")) {
list1.remove(i--);
//i--;
}
}
System.out.println(list1);
}
第一种:迭代器删除,代码如下:
private static void fun2() {
ArrayList<String> list1 = new ArrayList<>();
list1.add("a");
list1.add("b");
list1.add("b");
list1.add("c");
list1.add("d");list1.add("b");
// 迭代器删除
ListIterator<String> iterator = list1.listIterator();
while (iterator.hasNext()) {
String str = iterator.next();
if (str.equals("b")) {
iterator.remove();
}
}
System.out.println(list1);
}
五.Set集合
Set集合:无序 ,无下标 ,不重复。
主要是功能类。
HashSet: 去重
系统类,系统已经 重写好了HashCode和equals 方法,不需要人为再改如(Integer和String )。
而我们自己创建的类需要重写HashCode和equals 方法。
HoshCode()方法
系统每创建一个对象, 都会为这个对象 分配一个 hashCode值。
当向HashSet集合保存对象时,系统会先比较HashCode值是否相同
相同:是同一个对象
会调用对象的equals方法进行比较
如果equals方法也相同,那么这个值就不保存
反之 会存在集合中
不相同:
如果HashCode 不相同 相当于不是同一个对象 直接把对象 存入集合中(也不会调用equals方法)
一般会做到:
尽量让HashCode减少相同的次数
来提高程序的效率(即少调用equals方法)
代码:
public class Kll {
public static void main(String[] args) {
//随机10个数 [10, 20] 装到集合中 去重
HashSet<Integer> set = new HashSet<>();
for (int i = 0; i < 10; i++) {
int a = (int)(Math.random()*11 + 10);
//自动装箱
set.add(a);
}
System.out.println(set);
}
}