学习Java时的代码笔记,排版可能有些问题,代码拿来直接就可以用,毕竟全手打,难免会有错,欢迎指正
/*
集合类(集合框架):存储对象的一种方式
java.util.Collection
为什么出现集合类
面向对象的语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作
就对对象进行存储,集合就是存储对象最常用的一种方式
数组和集合类同是容器,有何不同
数组虽然也可以存储对象,但长度是固定的;而集合长度是可变的
数组中可以存储基本数据类型,集合只能存储对象
集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象
*/
import java.util.*;
class CollectionMainDemo1
{
public static void main(String[] args) {
method_retain();
base_method();
method_get();
}
public static void base_method()
{
//创建一个集合容器,使用Collection接口的子类,ArrayList
ArrayList al = new ArrayList();
//1.添加元素
/*
add方法的参数类型是Object以便接收任意类型的对象
集合中存储的都是对象的引用(地址)
*/
al.add("java01"); //add(Object obj)
al.add("java02");
al.add("java03");
al.add("java04");
sop(al);
//获取个数,集合长度
sop("size:"+al.size());
//删除元素
al.remove("java02");
//al.clear(); //清空集合
sop(al);
//判断元素
sop("java03是否存在"+al.contains("java03"));
sop("集合是否为空"+al.isEmpty());
}
public static void method_retain()
{
ArrayList al1 = new ArrayList();
al1.add("java01");
al1.add("java02");
al1.add("java03");
al1.add("java04");
ArrayList al2 = new ArrayList();
al2.add("java01");
al2.add("java02");
al2.add("java05");
al2.add("java06");
al1.retainAll(al2); //取交集,al1中只会保留和al2相同的元素
al1.removeAll(al2); //移除al1中和al2相同的元素
sop("al1:"+al1);
sop("al2:"+al2);
}
/*
迭代器
其实就是集合取出元素的方式
*/
public static void method_get()
{
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
Iterator it = al.iterator();//获取迭代器,用于取出集合中的元素
sop(it.next());
sop(it.hasNext()); //有元素时返回真
while(it.hasNext)
{
sop(it.next());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
/*
List集合共性方法
Collection
|--List:元素是有序的,元素可以重复,因为该集合体系有索引
|--ArrayList:底层是数组数据结构,特点:查询速度很快,增删改速度慢,元素越多越明显
|--LinkedList:底层是链表数据结构,特点:查询速度慢,增删改速度快
|--Vector:底层是数组数据结构,Vector是同步的,ArrayList是不同步的
|--Set:元素是无序的,元素不可以重复,因为该体系没有索引
|--HashSet:底层数据结构是hash表
HashSet是如何保证元素的唯一性的呢?
是通过元素的HashCode值相同,才会判断equals是否为true
如果元素的hashCode值不同,则不会调用equals
|--TreeSet:可以对Set集合中的元素进行排序
List:
特有方法:凡是可以操作角标的方法都是该体系特有的方法
增
add(index,element);
addAll(index,Collection);
删
remove(index);
改
set(index,element);
查
get(index);
subList(from,to);
listIterator();
*/
import java.util.*;
class ListMainDemo1
{
public static void main(String[] args) {
method_base();
listIteratorDemo();
}
public static void method_base()
{
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
//在指定位置添加元素
sop("原集合是:"+al);
al.add(1,"java09"); //在角标1的位置插入元素
sop("在角标1的位置插入元素后的结果是:"+al);
//删除指定位置的元素
al.remove(2);
sop("删除角标为2的元素后的结果是:"+al);
//修改元素
al.set(1,"java10");
sop("将角标为1的元素修改为java10后的结果:"+al);
//通过角标获取元素
sop("通过角标获取元素:"+al);
sop("获取到的元素:get(2):"+al.get(2));
//获取所有元素
sop("利用for循环获取所有元素:");
for(int x =0; x<al.size(); x++)
{
sop("al("+x+")="+al.get(x));
}
sop("利用Iterator获取所有元素:");
for(Iterator it = al.iterator(); it.hasNext(); )
{
sop("next:"+it.next());
}
//通过indexOf获取对象的位置
sop("通过indexOf获取java03所在的位置:"+al.indexOf("java03"));
//取一个子列表
List sub = al.subList(1,3);//从原集合中取出1到3的元素,包含1,不包含3
sop("sub="+sub);
}
/*
列表迭代器
ListIterator是Iterator的子接口
在迭代时,不可以通过集合对象的方法操作集合中的元素,因为会发生ConcurrentModificationException异常。
所以,在迭代时,只能用迭代器的方法操作元素,可是Iterator的方法是有限的,只能对元素进行判断,取出,删除
的操作,如果想要其他的操作,如添加,修改等,就需要使用其子接口,ListIterator。
该接口只能通过List集合的ListIterator方法获取
*/
public static void listIteratorDemo()
{
ArrayList al = new ArrayList();
al.add("java01");
al.add("java02");
al.add("java03");
al.add("java04");
sop("原集合是"+al);
/*在迭代过程中,准备添加或者删除元素
这种是有问题的方法
for(Iterator it = al.iterator(); it.hasNext(); )
{
Object obj = it.next();
if(obj.equals("java02"))
//al.add("java05"); //这里会抛出异常,因为连个容器在同时操作一个数据
it.remove();//将java02的引用从集合中删除
}
*/
for(ListIterator li = al.listIterator(); li.hasNext(); x++)
{
sop("hasNext():"+li.hasNext());
sop("hasPrevious():"+li.hasPrevious());
Object obj = li.next();
if(obj.equals("java02"))
{
//li.add("java05"); //在java02后面添加java05
li.set("java06"); //把java02修改成java06
}
}
sop("迭代以后的集合"+al);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
/*
Vector特殊的地方:枚举
枚举,就是Vector的特有取出方式
发现枚举和迭代器很象
此接口的功能与 Iterator 接口的功能是重复的。
此外,Iterator 接口添加了一个可选的移除操作,并使用较短的方法名。
新的实现应该优先考虑使用 Iterator 接口而不是 Enumeration 接口。
*/
class VectorMainDemo1
{
public static void main(String[] args) {
Vector v = new Vector();
v.add("java01");
v.add("java02");
v.add("java03");
v.add("java04");
Enumeration ne = v.elments();
while(en.hasMoreElements())
{
System.out.println(en.netElement());
}
}
}
/*
LinkedList模拟一个堆栈或者队列数据结构
堆栈:先进后出 First in Last out(FILO) 如同一个杯子
队列:先进先出 First in First out(FIFO) 如同一个水管
*/
import java.util.*;
class QueueMainDemo1
{
private LinkedList link;
QueueMainDemo1()
{
link = new LinkedList();
}
//添加方法
public void myAdd(Object obj)
{
link.addFirst(obj); //将指定元素插入到此列表的开头
}
//获取方法
public Object myGet()
{
return link.removeLast(); //返回此列表最后一个元素
}
//清空方法
public boolean isNull()
{
return link.isEmpty();
}
public static void main(String[] args) {
}
}
class LinkedListMainDemo1
{
public static void main(String[] args) {
QueueMainDemo1 q = new QueueMainDemo1();
q.myAdd("java01");
q.myAdd("java02");
q.myAdd("java03");
q.myAdd("java04");
System.out.println(q.myGet());
}
}
/*
练习:去除ArrayList中重复的元素
*/
import java.util.*;
class ArrayListTest1
{
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add("java01");
al.add("java01");
al.add("java02");
al.add("java02");
al.add("java03");
al.add("java03");
System.out.println(al);
al = singleElement(al);
System.out.println(al);
}
public static ArrayList singleElement(ArrayList al)
{
//定义一个临时容器
ArrayList newAl = new ArrayList();
for(Iterator it = al.iterator(); it.hasNext(); )
{
Object obj = it.next();
if(!newAl.contains(obj))//如果临时容器中,不包含原容器中的元素
newAl.add(obj); //就存入临时容器中
}
return newAl;
}
}
/*
ArrayList练习2
将自定义对象作为元素,存储到ArrayList集合中,并去除重复元素
比如:存人对象,同姓名同年龄,视为同一个人,为重复元素
List集合判断元素是否相同,依据的是元素的equals方法
*/
import java.util.*;
class Person
{
private String name;
private int age;
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public boolean equals(Object obj) //重写父类的equals方法,因为Object的equals方法比较的是地址
//为什么重写equals,因为contains底层用的就是equals
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
return this.name.equals(p.name) && this.age == p.age;
}
}
class ArrayListTest2
{
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add(new Person("lisi01",30));
al.add(new Person("lisi02",23));
al.add(new Person("lisi03",32));
al.add(new Person("lisi03",32));
al.add(new Person("lisi04",20));
al.add(new Person("lisi04",20));
Iterator it = al.iterator();
while(it.hasNext())
{
Person p = (Person)it.next();
System.out.println(p.getName()+"::"+p.getAge());
}
ArrayList al1 = singleElement(al);
System.out.println();
Iterator it1 = al1.iterator();
while(it1.hasNext())
{
Person p = (Person)it1.next();
System.out.println(p.getName()+"::"+p.getAge());
}
}
public static ArrayList singleElement(ArrayList al)
{
//定义一个临时容器
ArrayList newAl = new ArrayList();
for(Iterator it = al.iterator(); it.hasNext(); )
{
Object obj = it.next();
if(!newAl.contains(obj))//如果临时容器中,不包含原容器中的元素
newAl.add(obj); //就存入临时容器中
}
return newAl;
}
}
/*
Set: 无序,不可以重复元素.
|--HashSet: 数据结构是哈希表.线程是非同步的.
保证元素唯一性的原理:判断元素的hashCode值是否相同.
如果相同,还会继续判断元素的equals方法
|--TreeSet: 可以对Set集合中的元素进行排序.
底层数据结构是二叉树.
保证元素的唯一性的依据是compareTo方法return 0.
TreeSet排序的第一种方式:让元素自身具备比较性,元素需要实现compareable接口
覆盖compareTo方法,这种方式也称为元素的自然顺序,或者叫做默认顺序
TreeSet排序的第二种方式:当元素自身不具备比较性或比较性不是所需要的时候
就需要让集合自身具备比较性,在集合初始化时就有了比较方式,所以我们需要
参阅集合的构造函数
*/
class HashSetMainDemo1
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add("java01");
hs.add("java02");
hs.add("java03");
hs.add("java04");
Iterator it = hs.iterator();
while(it.hasNext())
{
sop(it.next());
}
}
}
/*
HashSet添加自定义对象
*/
import java.util.*;
/*
在实际开发中,只要描述这个事物要往集合里面存
一般都会重写hashCode() 和 equals()方法
*/
class Person
{
private String name;
private int age;
public static void main(String[] args) {
}
Person(String name,int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return this.name;
}
public int getAge()
{
return this.age;
}
/*
重写hashCode,因为hashSet给每个对象赋了不同的hash值,所以equals没有运行
所以这里重写hash值,让每个对象hash值相同,这时候equals就运行了
*/
public int hashCode()
{
System.out.println(this.name+"....hashCode");
return name.hashCode()+age*37; //乘整数是为了保证hash值得唯一性
}
/*
重写equals因为默认的equals是判断地址
*/
public boolean equals(Object obj)
{
if(!(obj instanceof Person))
return false;
Person p = (Person)obj;
System.out.println(this.name+"...equals.."+p.name);
return this.name.equals(p.name) && this.age == p.age;
}
}
class HashSetMainDemo2
{
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person("a1",11));
hs.add(new Person("a2",12));
hs.add(new Person("a3",13));
hs.add(new Person("a4",14));
hs.add(new Person("a4",14));
//对于判断元素是否存在以及删除等操作,都依赖于元素的hashCode()和equals()
System.out.println(hs.contains(new Person("a1",11))); //
hs.remove(new Person("a2",12));
Iterator it = hs.iterator();
while(it.hasNext())
{
Person p = (Person)it.next();
System.out.println(p.getName()+"::"+p.getAge());
}
}
}
/*
TreeSet:可以对Set集合中的元素进行排序
默认按照Ascii码表排序
*/
class TreeSetMainDemo1
{
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add("cbcd");
ts.add("bsdf");
ts.add("aaaa");
ts.add("ebd");
Iterator it = ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
/*
存储自定义对象
需求往TreeSet集合中存储自定义对象学生
想按照学生的年龄进行排序
*/
import java.util.*;
class Student
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class TreeSetMainDemo2
{
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20)); //2个以上对象会报错
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi01",40));
Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
/*
以上结果会报错,因为TreeSet在排序的时候,我们的对象
根本不具备比较性,说白了就是,TreeSet根本不知道你排
序的依据是什么,那么它怎么知道该如何给你排序呢?所以
会报错,那么因此,如果我们想进行排序该怎么办呢?
答:
想要进行排序那么我们必须具备比较性,那么我们又如何
才能具备比较性呢?
TreeSet给我们提供了一个接口Comparable,你只要实现这个
接口,那么就具备了比较性,TreeSet就可以帮你进行排序了
*/
import java.util.*;
class Student implements Comparable //该接口强制让学生具备比较性
{
private String name;
private int age;
public int compareTo(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;
System.out.println(this.name+"...compareto..."+s.name); //比较过程
if(this.age>s.age)
return 1; //如果大于返回整数
if(this.age==s.age) //如果等于返回0;0表示两个对象相等
{
return this.name.compareTo(s.name); //如果主要比较因素相等,就比较次要因素
//它返回的也是0、1、或负数
}
return -1; //小于返回负数
}
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class TreeSetMainDemo3
{
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi01",40));
ts.add(new Student("lisi03",40));
Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
/*
二叉树:可以减少比较次数,提高性能
二叉树在元素越多的时候,它会自动取折中值
二叉树默认按照从小到大取数据
*/
//需求,数据怎么存进去的怎么取出来
import java.util.*;
class Student implements Comparable //该接口强制让学生具备比较性
{
private String name;
private int age;
public int compareTo(Object obj) //TreeSet集合在比较的时候和compareTo没关系,它只看compareTo的返回值
{
return 1; //代表待比较的数比源数据大,因为二叉树默认按照从小到大取数据,所以怎么存进去的怎么取
//如果想倒序取数据,直接返回-1即可
}
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class TreeSetMainDemo4
{
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi01",40));
ts.add(new Student("lisi03",40));
Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
/*
TreeSet第二种排序方式:实现Comparator
当元素自身不具备比较性或比较性不是所需要的时候
这时需要让容器自身具备比较性
定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数
当两种排序都存在时以比较器为主
*/
import java.util.*;
class Student implements Comparable //该接口强制让学生具备比较性
{
private String name;
private int age;
public int compareTo(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Student s = (Student)obj;
System.out.println(this.name+"...compareto..."+s.name); //比较过程
if(this.age>s.age)
return 1; //如果大于返回整数
if(this.age==s.age) //如果等于返回0;0表示两个对象相等
{
return this.name.compareTo(s.name); //如果主要比较因素相等,就比较次要因素
//它返回的也是0、1、或负数
}
return -1; //小于返回负数 return 1;
}
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
class TreeSetMainDemo4
{
public static void main(String[] args) {
TreeSet ts = new TreeSet(new MyCompare()); //定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi01",40));
ts.add(new Student("lisi03",40));
Iterator it = ts.iterator();
while(it.hasNext())
{
Student stu = (Student)it.next();
System.out.println(stu.getName()+"..."+stu.getAge());
}
}
}
class MyCompare implements Comparator //比较器
{
public int compare(Object o1,Object o2)
{
Student s1 = (Student)o1;
Student s2 = (Student)o2;
return s1.getName().compareTo(s2.getName()); //以姓名进行排序
}
}
/*
练习:按照字符串长度排序
字符串本身具备比较性,但是它的比较方式不是所需要的
这时候就只能使用比较器
*/
import java.util.*;
class TreeSetTest1
{
public static void main(String[] args)
{
TreeSet ts = new TreeSet(new StringLengthComparator());
al.add("ts01");
al.add("ts022");
al.add("ts0312");
Iterator it = ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
class StringLengthComparator implements Comparator
{
public int compare(Object o1,Object o2)
{
String s1 = (String)o1;
String s2 = (String)o2;
/*
if(s1.length()>s2.length());
return 1;
if(s1.length()==s2.length())
return 0;
return -1;
*/
int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
if(num==0)
return s1.compareTo(s2); //主要条件要是比较不出来就比较次要元素
return num;
}
}
/*
当我们向集合中存放不同类型的数据时运行时可能会出错
泛型集合:JDK1.5版本以后出现的新特性。用于解决安全问题,是一种安全机制
好处
1.将运行时期出现的ClassCastException错误,转移到了编译时期,方便于程序员解决问题
让运行时期问题减少,安全
2.避免了强制转换的麻烦.
泛型格式:通过<>来定义要操作的引用数据类型
在使用java提供的对象时,什么时候写泛型呢?
答:
通常在集合框架中很常见,只要见到<>就要定义泛型,其实<>就是用来接收类型的
当使用集合时,将集合中要存储的数据类型作为参数传递到<>即可,如同函数传参数一样
*/
import java.util.*;
class GenericDemo1
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>(); //定义一个ArrayList容器,该容器是String类型
al.add("abc01");
al.add("abc02");
al.add("abc03");
Iterator<String> it = al.iterator();
while(it.hasNext())
{
String s = it.next();
System.out.println(s+":"+s.length());
}
}
}
//泛型在比较器中的应用
import java.util.*;
class GenericDemo2
{
public static void main(String[] args)
{
TreeSet<String> ts = new TreeSet<String>(new LenComparator());
al.add("ts01");
al.add("ts022");
al.add("ts0312");
Iterator<String> it = ts.iterator();
while(it.hasNext())
{
String s = it.next();
System.out.println(s);
}
}
}
class LenComparator implements Comparator<String> //比较器也可以加泛型,避免强转
{
public int compare(String o1,String o2)
{
int num = new Integer(o1.length()).compareTo(new Integer(o2.length());//按长度比较
if(num==0)
return o1.compareTo(o2);
return num;
}
}
/*
泛型类
什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候
早期定义Object来完成扩展
现在定义泛型来完成扩展
*/
class Worker
{
}
class Student
{
}
//泛型前
/*
class Tool
{
private Object obj;
public void setObject(Object obj)
{
this.obj = obj;
}
public Object getObject()
{
return obj;
}
}
*/
//泛型后
class Utils<Generics>
{
private Generics g;
public void setObject(Generics g)
{
this.g = g;
}
public Generics getObject()
{
return g;
}
}
class GenericDemo3
{
public static void main(String[] args)
{
Utils<Worker> u = new Utils<Worker>();
u.setObject(new Worker());
Worker w = u.getObject(); //避免了强转,直接让错误转移到了编译时期
/*
Tool t = new Tool();
t.setObject(new Student());
Worker w = (Worker)t.getObject(); //在出现泛型之前需要进行强转
*/
}
}
/*
泛型方法
*/
class Demo<T>
{
public void show(T t)
{
System.out.println("Show: " + t);
}
public void print(T t)
{
System.out.println("Print: " + t);
}
}
class GenericDemo4
{
public static void mian(String[] args)
{
Demo<Integer> d = new Demo<Integer>();
d.show(new Integer(4));
d.print("haha"); //这样就会报错,因为new对象时已经指明类型为Integer
}
}
/*
以上就是泛型类的一个局限性
泛型类定义的泛型,在整个类中有效。如果被方法使用
那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了
为了让不同方法可以操作不同的类型,而且类型还不确定
那么可以将泛型定义在方法上
*/
class Demo
{
public<T> void show(T t)
{
System.out.println("Show: " + t);
}
public<T> void print(T t)
{
System.out.println("Print: " + t);
}
}
class GenericDemo5
{
public static void main(String[] args)
{
Demo d = new Demo();
d.show("haha");
d.show(new Integer(4));
}
}
/*
静态泛型方法
静态方法不可以访问类上定义的泛型,如果静态方法操作的的应用数据类型不确定,可以将泛型定义在方法上
*/
class Demo<T>
{
public void show(T t)
{
System.out.println("Show: " + t);
}
public<Q> void print(Q q)
{
System.out.println("Print: " + t);
}
public static<W> void method(W w) //静态泛型方法
{
}
}
class GenericDemo5
{
public static void main(String[] args)
{
Demo<String> d = new Demo<String>();
d.show("haha");
d.print(5);
d.print("hehe");
Demo.method("hahaha");
}
}
/*
泛型接口
*/
interface Inter<T>
{
void show(T t);
}
/*
class Interimpl implements Inter<String>
{
public void show(String t)
{
System.out.println("Show: " + t);
}
}
*/
class InterImpl<T> implements Inter<T>
{
public void show(T t)
{
System.out.println("Show: " + t);
}
}
class GenericDemo6
{
public static void main(String[] args)
{
InterImpl<Integer> i = new InterImpl<Integer>();
i.show(4);
/*
InterImpl i = new InterImpl();
i.show("haha");
*/
}
}
/*
泛型限定
?通配符。也可以理解为占位符
泛型的限定:
限定?可接受的类型范围
? extends E: 可以接收E类型或者E的子类型 上限定(上限)
? super E: 可以接收E类型或者E的父类型 下限定(下限)
*/
//上限应用
import java.util.*;
class GenericDemo7
{
/*
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("abc01");
al.add("abc02");
al.add("abc03");
ArrayList<Integer> al1 = new ArrayList<Integer>();
al1.add(4);
al1.add(8);
al1.add(1);
printColl(al);
printColl(al1);
}
// public static void printColl(ArrayList<String> al) //ArrayList<String> al = new ArrayList<Integer>(); Error
public static void printColl(ArrayList<?> al) //ArrayList<?> al = new ArrayList<Integer>();
{
Iterator<?> it = al.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
*/
class Person
{
private String name;
Persion(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
class Student extends Person
{
Student(String name)
{
super(name);
}
}
public static void main(String[] args)
{
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Person("abc01"));
al.add(new Person("abc02"));
al.add(new Person("abc03"));
ArrayList<Student> al1 = new ArrayList<Student>();
al1.add(new Student("abc01"));
al1.add(new Student("abc02"));
al1.add(new Student("abc03"));
printColl(al); //ArrayList<Person> al = new ArrayList<Student>();
}
public static void printColl(ArrayList<? extends Person> al) //限定?可接受的类型范围,只能打印Person和Person的子类
{
Iterator<? extends Person> it = al.iterator(); //这里只能打印Person和Person的子类
while(it.hasNext())
{
System.out.println(it.next().getName());
}
}
}
/*
泛型限定2--下限应用
*/
import java.util.*;
class GenericDemo8
{
public static void main(String[] args)
{
/*
TreeSet<Student> ts = new TreeSet<Student>(new StuComp());
ts.add(new Student("abc01");
ts.add(new Student("abc02");
ts.add(new Student("abc03");
Iterator<Student> it = ts.iterator();
while(it.hasNext())
{
System.out.println(it.next().getName());
}
TreeSet<Worker> ts1 = new TreeSet<Worker>(new WorkComp());
ts1.add(new Worker("abc-01");
ts1.add(new Worker("abc-02");
ts1.add(new Worker("abc-03");
Iterator<Worker> it1 = ts1.iterator();
while(it1.hasNext())
{
System.out.println(it1.next().getName());
}
*/
TreeSet<Student> ts = new TreeSet<Student>(new Comp());
ts.add(new Student("abc01");
ts.add(new Student("abc02");
ts.add(new Student("abc03");
Iterator<Student> it = ts.iterator();
while(it.hasNext())
{
System.out.println(it.next().getName());
}
TreeSet<Worker> ts1 = new TreeSet<Worker>(new Comp());
ts1.add(new Worker("abc-01");
ts1.add(new Worker("abc-02");
ts1.add(new Worker("abc-03");
Iterator<Worker> it1 = ts1.iterator();
while(it1.hasNext())
{
System.out.println(it1.next().getName());
}
}
}
/*
class StuComp implements Comparator<Student> //Student的比较器
{
public int compare(Student s1,Student s2)
{
return s1.getName().compareTo(s2.getName());
}
}
class WorkComp implements Comparator<Worker> //Worker的比较器
{
public int compare(Worker w1,Worker w2)
{
return w1.getName().compareTo(w2.getName());
}
}
*/
//以上没比较一个对象需要创建一个比较器,非常麻烦
class Comp implements Comparator<Person>
{
public int compare(Person p1,Person p2)
{
return p1.getName().compareTo(p2.getName());
}
}
class Person
{
private String name;
Person(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
public String toString()
{
return "Person: " + name;
}
}
class Student extends Person
{
Student(String name)
{
super(name);
}
}
class Worker extends Person
{
Worker(String name)
{
super(name);
}
}
/*
Map集合,集合存储的是键值对,必须要保证键的唯一性
1.添加
put(K key,V value);
putAll(Map<? extends K,? extends V>m);
2.删除
clear();
remove(Object key);
3.判断
containsValue(Object value);
containsKey(Object key);
isEmpty();
4.获取
get(Object key);
size();
values();
entrySet();
keySet();
Map:Map和Set很像,Set底层就是使用的Map集合
|--Hashtable:底层是哈希表数据结构,不可以存入null键或者null值,该集合是线程同步的
|--HashMap:底层是哈希表数据结构,并允许使用null键或null值,该集合是不同步的
|--TreeMap:底层是二叉树数据结构,线程不同步,可以用于给Map集合中的键排序
*/
//Map的共性方法
import java.util.*;
class MapDemo1
{
public static void main(String[] args)
{
//添加元素,如果出现相同的键,那么后添加的值会覆盖原有的键对应的值,put方法会返回原有的值
Map<String,String> map = new HashMap<String,String>();
map.put("01","zhangsan01");
map.put("02","zhangsan02");
map.put("03","zhangsan03");
//判断
System.out.println("containsKey:" + map.containsKey("02"));
//移除
System.out.println("remove:" + map.remove("03"));
System.out.println(map);
//获取
System.out.println("get:" + map.get("02"));
map.put("04",null);
System.out.println("get:" + map.get("04"));//可以通过get方法的返回值来判断一个键是否存在
//获取map集合中的所有值
Collection<String> coll = map.values();
System.out.println(coll);
System.out.println(map);
}
}
/*
Map集合的两种取出方式:
1. Set<key> keySet:将Map中所有的键存入到Set集合中,因为Set集合具备迭代器。
所以可以通过迭代方式取出所有的键,然后再根据get方法,获取每一个键对应的值。
map集合的取出原理:将map集合转换成set集合,再通过迭代器取出
*/
import java.util.*;
class MapDemo2
{
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String,String>();
map.put("01","zhangsan01");
map.put("02","zhangsan02");
map.put("03","zhangsan03");
map.put("04","zhangsan04");
//先获取map集合中的所有键的set集合,keySet();
Set<String> keySet = map.keySet();
//有了Set集合就可以获取其迭代器
Iterator<String> it = keySet.iterator();
while(it.hasNext())
{
String key = it.next();
//有了键就可以通过map集合的get方法获取其对应的值
String value = map.get(key);
System.out.println("key:" + key + ",value:" + value);
}
}
}
/*
2. Set<Map.Entry<k,v>> entrySet:将map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry
Map.Entry相当于一个关系类型,获取到Map.Entry对象后就可以通过Map.Entry中的getKey和getValue方法获取键和值
*/
import java.util.*;
class MapDemo3
{
public static void main(String[] args)
{
Map<String,String> map = new HashMap<String,String>();
map.put("01","zhangsan01");
map.put("02","zhangsan02");
map.put("03","zhangsan03");
map.put("04","zhangsan04");
Set<Map.Entry<String,String>> entrySet = map.entrySet();
Iterator<Map.Entry<String,String>> it = entrySet.iterator();
while(it.hasNext())
{
Map.Entry<String,String> me = it.next();
String key = me.getKey(); //getKey方法获取关系映射中的键
String value = me.getValue(); //getValue方法获取关系映射中的值
System.out.println(key + ":" + value);
}
}
}
/*
Map.Entry其实Entry也是一个接口,它是Map接口中的一个内部接口
它是通过内部类实现的
*/
interface Map
{
public static interface Entry
{
public abstract Object getKey();
public abstract Object getValue();
}
}
class HashMap implements Map
.Entry
{
class Haha implements Map.Entry
{
public Object getKey()
{
}
public Object getValue()
{
}
}
}
/*
Map练习
每一个学生都有对应的归属地
学生Student,地址String
学生属性: 姓名,年龄
注意:姓名和年龄相同的视为同一个学生
保证学生的唯一性
1.描述学生
2.定义map容器,将学生作为键,地址作为值,存入
3.获取map集合中的元素
*/
import java.util.*;
class Student implements Comparable<Student> //实现比较器
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Student s) //重写比较器
{
int num = new Integer(this.age).compareTo(new Integer(s.age));
if(num==0)
return this.name.compareTo(s.name);
return num;
}
public int hashCode()
{
return name.hashCode() + age * 34;
}
public boolean equals(Object obj) //重写equals方法
{
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s = (Student)obj;
return this.name.equals(s.name) && this.age == s.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name + ":" + age;
}
}
class MapTest1
{
public static void main(String[] args)
{
HashMap<Student,String> hm = new HashMap<Student,String>();
hm.put(new Student("lisi1",21),"beijing");
hm.put(new Student("lisi2",22),"shanghai");
hm.put(new Student("lisi3",23),"tianjin");
hm.put(new Student("lisi4",24),"chengdu");
//第一种取出方式keySet 第一种取出方式keySet hash表示无序的
Set<Student> keySet = hm.keySet();
Iterator<Student> it = hm.keySet().iterator();
while(it.hasNext())
{
Student stu = it.next();
String addr = hm.get(stu);
System.out.println(stu + " keySet: " + addr);
}
//第二种取出方式entrySet 第一种取出方式entrySet
Set<Map.Entry<Student,String>> entrySet = hm.entrySet();
Iterator<Map.Entry<Student,String>> iter = entrySet.iterator();
while(iter.hasNext())
{
Map.Entry<Student,String> me = iter.next();
Student stu = me.getKey();
String addr = me.getValue();
System.out.println(stu + " entrySet: " + addr);
}
}
}
/*
TreeMap练习
需求:对学生对象的年龄进行升序排序
因为数据是以键值对形式存在的
所以要使用可以排序的Map集合.TreeMap
*/
import java.util.*;
class Student implements Comparable<Student> //实现比较器
{
private String name;
private int age;
Student(String name,int age)
{
this.name = name;
this.age = age;
}
public int compareTo(Student s) //重写比较器
{
int num = new Integer(this.age).compareTo(new Integer(s.age));
if(num==0)
return this.name.compareTo(s.name);
return num;
}
public int hashCode()
{
return name.hashCode() + age * 34;
}
public boolean equals(Object obj) //重写equals方法
{
if(!(obj instanceof Student))
throw new ClassCastException("类型不匹配");
Student s = (Student)obj;
return this.name.equals(s.name) && this.age == s.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public String toString()
{
return name + ":" + age;
}
}
class StuNameComparator implements Comparator<Student>
{
public int compare(Student s1,Student s2)
{
int num = s1.getName().compareTo(s2.getName());
if(num==0)
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge())); //次要条件
return num;
}
}
class MapTest2
{
public static void main(String[] args)
{
TreeMap<Student,String> tm = new TreeMap<Student,String>(new StuNameComparator());
tm.put(new Student("lisi1",21),"beijing");
tm.put(new Student("lisi2",22),"shanghai");
tm.put(new Student("lisi3",23),"tianjin");
tm.put(new Student("lisi4",24),"chengdu");
Set<Map.Entry<Student,String>> entrySet = tm.entrySet();
Iterator<Map.Entry<Student,String>> it = entrySet.iterator();
while(it.hasNext())
{
Map.Entry<Student,String> me = it.next();
Student stu = me.getKey();
String addr = me.getValue();
System.out.println(stu + ":::" + addr);
}
}
}
/*
map集合扩展知识:map集合被使用是因为具备映射关系
集合嵌套应用
一个学校有多个教室,每个教室都有名称
学校
|--教室1
|--01,zhangsan
|--02,lisi
|--教室2
|--01,wangwu
|--02,zhaoliu
*/
import java.util.*;
class MapExtend
{
public static void main(String[] args)
{
HashMap<String,HashMap<String,String>> school = new HashMap<String,HashMap<String,String>>(); //创建学校
HashMap<String,String> classroom1 = new HashMap<String,String>(); //创建教室1
HashMap<String,String> classroom2 = new HashMap<String,String>(); //创建教室2
school.put("classroom1",classroom1); //1对多
school.put("classroom2",classroom2); //1对多
classroom1.put("01","zhangsan"); //向教室添加学生
classroom1.put("02","lisi"); //向教室添加学生
classroom2.put("01","wangwu"); //向教室添加学生
classroom2.put("02","zhaoliu"); //向教室添加学生
//变量学校集合,获取所有教室
Iterator<String> it = school.keySet().iterator();
while(it.hasNext())
{
String roomName = it.next();
HashMap<String,String> room = school.get(roomName);
getStudentInfo(room); //获取所有教室的学生
}
}
public static void getStudentInfo(HashMap<String,String> roomMap)
{
Iterator<String> it = roomMap.keySet().iterator();
while(it.hasNext())
{
String id = it.next();
String name = roomMap.get(id);
System.out.println(id + ":" + name);
}
}
}
/*
集合框架的工具类
Collections-binarySearch
Collections-max
Collections-sort
*/
import java.util.*;
class CollectionsDemo1
{
public static void main(String[] args)
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("zz");
list.add("qq");
list.add("q");
sop(list);
int index = halfSearch2(list,"zz",new StrLenComparator());
}
public static void binarySearchDemo()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("zz");
list.add("qq");
list.add("q");
sop(list);
Collections.sort(list);
sop(list);
int index = Collections.binarySearch(list,"aaa"); //二分查找
sop("index=" + index);
}
public static int halfSearch(List<String> list,String key) //binarySearch原理
{
int max,min,mid;
max = list.size()-1;
min = 0;
while(min<=max)
{
mid = (max+min)>>1; // /2
String str = list.get(mid);
int num = str.compareTo(key);
if(num>0)
max = mid - 1;
else if(num<0)
min = mid + 1;
else
return mid;
}
return -min-1;
}
public static int halfSearch2(List<String> list,String key,Comparator<String> comp) //binarySearch原理带比较器
{
int max,min,mid;
max = list.size()-1;
min = 0;
while(min<=max)
{
mid = (max+min)>>1; // /2
String str = list.get(mid);
int num = comp.compare(str,key)
if(num>0)
max = mid - 1;
else if(num<0)
min = mid + 1;
else
return mid;
}
return -min-1;
}
public static void maxDemo()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("zz");
list.add("qq");
list.add("q");
sop(list);
String max = Collections.max(list); //取最大值
sop("max:" + max);
}
public static void sortDemo()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("zz");
list.add("qq");
list.add("q");
sop(list);
Collections.sort(list,new StrLenComparator()); //给list集合排序
sop(list);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
class StrLenComparator implements Comparator<String> //实现比较器
{
public int compare(String s1,String s2)
{
if(s1.length()>s2.length())
return 1;
if(s1.length()<s2.length())
return -1;
return s1.compareTo(s2)
}
}
/*
Collections-替换反转
*/
import java.util.*;
class CollectionsDemo2
{
public static void main(String[] args)
{
}
public static void replaceAllDemo()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("zz");
list.add("kkkkk");
sop(list);
Collections.replaceAll(list,"aaa","www"); //替换
Collections.reverse(list); //反转
sop(list);
}
/*
fill方法可以将list集合中的所有元素替换成指定元素
练习:将list集合中的部分元素替换成指定元素
*/
public static void fillDemo()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("zz");
list.add("kkkkk");
sop(list);
Collections.fill(list,"pp"); //将集合中的元素全部替换成"pp"
sop(list);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
/*
Collections-reverseOrder 逆向比较器
reverseOrder还可以强行逆向指定比较器
*/
import java.util.*;
class CollectionsDemo3
{
public static void main(String[] args)
{
reverseOrderDemo();
}
public static void reverseOrderDemo()
{
//TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder()); //传入逆向比较器
TreeSet<String> ts = new TreeSet<String>(Collections.reverseOrder(new StrLenComparator())); //逆向指定比较器
ts.add("abcd");
ts.add("aaa");
ts.add("zz");
ts.add("kkkkk");
Iterator it = ts.iterator();
while(it.hasNext())
{
sop(it.next());
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
class StrLenComparator implements Comparator<String> //实现比较器
{
public int compare(String s1,String s2)
{
if(s1.length()>s2.length())
return 1;
if(s1.length()<s2.length())
return -1;
return s1.compareTo(s2);
}
}
/*
Collections-swap //置换
Collections-shuffle //随机置换
*/
import java.util.*;
class CollectionsDemo2
{
public static void main(String[] args)
{
swapDemo();
}
public static void swapDemo()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("zz");
list.add("kkkkk");
sop(list);
Collections.swap(list,1,2); //指定角标置换
sop(list);
}
public static void shuffleDemo()
{
List<String> list = new ArrayList<String>();
list.add("abcd");
list.add("aaa");
list.add("zz");
list.add("kkkkk");
sop(list);
Collections.shuffle(list); //随机置换
sop(list);
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
/*
集合框架工具类Arrays,用于操作数组的工具类
里面都是静态方法
asList: 将数组转换为List集合
*/
import java.util.*;
class ArraysDemo
{
public static void main(String[] args)
{
// int[] arr = {2,4,5};
// System.out.println(Arrays.toString(arr));
String[] arr = {"abc","cc","kkkk"};
/*
把数字变成集合的好处:
可以使用集合的思想和方法来操作数组中的元素
注意:将数组变为集合,不可以使用集合的增删方法
因为数组的长度是固定的
*/
List<String> list = Arrays.asList(arr); //将数组转换为List集合
//list.add("qq"); //UnsupportedOperationException
System.out.println(list);
/*
如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转成集合中的元素
如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在。
*/
int[] nums = {2,4,5};
List<int[]> li = Arrays.asList(nums); //这里泛型要指定int[]数组类型才行
System.out.println(li);
}
}
/*
集合变数组
Collection接口中的toArray方法
*/
import java.util.*;
class CollectionToArrayDemo
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("abc01");
al.add("abc02");
al.add("abc03");
/*
1.指定类型的数组到底要定义多长呢?
当指定类型的数组长度小于了集合的size,那么该方法的内部会创建一个新的数组,长度为集合的size。
当指定类型的数组长度大于了集合的size,那么就不会新创建数组,而是使用传递进来的数组
所以创建一个刚刚好的数组最为合适
2.为什么要将集合变数组?
为了限定对元素的操作.如果你把集合返回给对方,对方依然可以对集合进行增删
而如果你把集合转成数组返回去,那么数组的长度是固定的,对方就无法对集合进行增删
*/
String[] arr = al.toArray(new String[al.size()]); //保证数组长度刚刚好
System.out.println(Arrays.toString(arr));
}
}
/*
高级for循环
格式:
for(数据类型 变量名 : 被遍历的集合(Collection)或者数组)
{
只能获取集合元素,但是不能对集合进行操作
迭代器除了遍历,还可以进行remove集合中的元素的动作
如果是用了ListIterator,还可以在遍历过程中对集合进行增删改查的动作
}
*/
import java.util.*;
class ForEachDemo
{
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("abc01");
al.add("abc02");
al.add("abc03");
/*
Iterator<String> it = al.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
*/
/*
JDK1.5以后可以用for循环遍历集合
底层还是用的迭代器,为了简化书写
*/
for(String s : al) //s第一次指向了集合中的第一个元素
{
s = "kk";
System.out.println(s);
}
System.out.println(al);
//以上循环其实是有局限性的,它只能对集合中的元素做取出,而不能做修改操作
/*
传统for循环和高级for循环有什么区别呢?
高级for循环有一个局限性,必须有被遍历的目标。
建议在遍历数组的时候,还是希望是用传统的for,因为传统的for循环可以定义角标
*/
int[] arr = {3,5,1};
for(int i : arr)
{
System.out.println("i:" + i);
}
HashMap<Integer,String> hm = new HashMap<Integer,String>();
hm.put(1,"a");
hm.put(2,"b");
hm.put(3,"c");
Set<Integer> keySet = hm.keySet();
for(Integer i : keySet)
{
System.out.println(i+ "::" + hm.get(i));
}
//上面的简写形式
for(Map.Entry<Integer,String> me : hm.entrySet())
{
System.out.println(me.getKey()+"---"+me.getValue());
}
}
}
/*
JDK1.5版本以后出现的新特性-可变参数
方法的可变参数,在使用时注意:
可变参数一定要定义在参数列表的最后面
*/
class ParamMethodDemo
{
public static void main(String[] args)
{
/*
int[] arr = {3,4};
show(arr);
int[] arr1 = {2,3,5,6};
show(arr1);
*/
show("hell world",2,3,4,5);
}
//很麻烦,多一个参数重载一次
/*
public static void show(int a,int b)
{
System.out.println(a+","+b);
}
public static void show(int a,int b,int c)
{
}
*/
//用数组还不麻烦,因为每次要new一个数组
/*
public static void show(int[] arr)
{
}
*/
/*
其实这种方法还是数组,但是我们省去了new数组的操作
这种方法叫可变参数
*/
public static void show(String str,int... arr) //可变参数一定要定义在参数列表的最后面
{
System.out.println(arr.length); //这里arr是一个数组,长度是你传入的值
}
}
/*
静态导入
当类名重名时,需要指定具体的包名
当方法重名时,需要指定具备所属的对象或者类
*/
import java.util.*;
import static java.util.Arrays.*; //导入的是Arrays这个类中的所有静态成员
import static java.lang.System.*; //导入了System类中的所有静态成员.
class StaticImport
{
public static void main(String[] args)
{
int[] arr = {3,1,5};
/*
Arrays.sort(arr);
int index = Arrays.binarySearch(arr,1);
System.out.println(Arrays.toString(arr));
System.out.println("Index=" + index);
*/
/*
导入静态成员后就可以不用再写类名.
*/
sort(arr);
int index = binarySearch(arr,1);
System.out.println(Arrays.toString(arr)); //这里方法重名,所以不能省略
System.out.println("Index=" + index);
out.println("Hello World"); //省略System.
}
}