1. java.util.Collection: 集合,用于存储一组元素。提供了维护集合的相关操作。其派生了两个子接口:List:可重复集 Set:不可重复集。元素是否重复是依靠自身equals方法比较的结果而定的。
Collection c=new ArrayList();
/*1.
* boolean add(E e) 向集合中添加元素
* 当元素成功添加到集合后返回true
*/
//集合里面尽可能放类型相同的元素 方便拿
c.add("one");
c.add("two");
c.add("three");
System.out.println(c);
/*2.
* int size()
* 返回当前集合的元素个数
*/
System.out.println("size:"+c.size());//size:3
/*3.
* boolean ieEmpty()
* 判断当前集合是否不含任何元素 --空集合
* 当size为0的时候就是空集合
*/
boolean isEmpty=c.isEmpty();
System.out.println("是否是空集:"+isEmpty);//false
/*4.
* void clear()
* 清空集合元素
*/
System.out.println("清空集合");
c.clear();
System.out.println("size:"+c.size());//size:0
System.out.println("是否是空集:"+c.isEmpty());//是否是空集:true
2. boolean contains(E e): 判断当前集合是否包含给定元素
public static void main(String[] args) {
Collection c=new ArrayList();
c.add(new Point(1,2));
c.add(new Point(3,4));
c.add(new Point(5,6));
System.out.println(c);
Point p=new Point(1,2);
// c.add(p);
/*
* 集合判断是否包含指定元素是依靠元素的equals比较的结果。
* 只要集合中有元素与给定元素比较为true,则认为包含
*/
boolean contains=c.contains(p);
System.out.println("包含:"+contains);//包含:true
}
3. 集合存放元素存放的是元素的引用(地址)
public static void main(String[] args) {
Collection c=new ArrayList();
Point p=new Point(1,2);
c.add(p);
System.out.println("p:"+p);//p:(1,2)
System.out.println(c);//[(1,2)]
p.setX(2);
System.out.println("p:"+p);//p:(2,2)
System.out.println(c);//[(2,2)]
}
4. 删除集合元素
Collection c=new ArrayList();
c.add(new Point(1,2));
c.add(new Point(3,4));
c.add(new Point(5,6));
System.out.println(c);//[(1,2), (3,4), (5,6)]
Point p=new Point(1,2);
/*
* boolean remove(E e)
* 从集合中删除指定元素,删除成功返回true
* 只删除集合中第一个与给定元素equals比较为true的元素--只删除一个元素
*/
c.remove(p);
System.out.println("删除完毕");
System.out.println(c);//[(3,4), (5,6)]
5. 集合的批量操作
Collection c1=new ArrayList();
c1.add("java");
c1.add("c++");
c1.add(".net");
System.out.println("c1:"+c1);
Collection c2=new HashSet();//无序的,不能有重复的元素
c2.add("ios");
c2.add("android");
c2.add("linux");
System.out.println("c2:"+c2);
/*
* 取并集
* boolean addAll(Collection c)
* 将给定集合中的所有元素添加到当前集合中,添加后只要当前集合元素数量发生了变化,则返回true
*/
boolean flag=c2.addAll(c1);
System.out.println("取并集后的c2:"+c2);
System.out.println(flag);
Collection c3=new ArrayList();
c3.add("java");
c3.add("android");
/*
* boolean containsAll(Colletion c)
* 判断当前集合是否包含给定集合中的所有元素
*/
boolean contains=c1.containsAll(c3);
System.out.println("全包含:"+contains);
/*
* 从c1集合中删除两个集合中共有的元素
*/
c1.removeAll(c3);
System.out.println(c1);
6. 遍历集合 Collection提供了统一的遍历集合元素的方式:迭代器模式,Iterator iterator() 获取用于遍历当前集合的迭代器。java.util.Iterator是一个接口,规定了用于遍历集合元素的相关方法,不同的集合提供了相应的实现类。遍历集合遵循:问,取,删的步骤,其中删除不是必须操作
Collection c=new ArrayList();
c.add("one");
c.add("#");
c.add("two");
c.add("#");
c.add("three");
c.add("#");
c.add("four");
Iterator it=c.iterator();//获取用于遍历当前集合的迭代器
/*
* boolean hasNext() 问的过程
* 该方法是判断集合中是否还有元素可以取出。如果集合中没有元素,直接取,会报错
*
* E next() 取的过程 获取集合中下一个元素
*/
while(it.hasNext()){//问集合中是否还有元素
String str=(String)it.next();
if("#".equals(str)){//比 str.equals("#")更好的原因是不会引发空指针异常
//c.remove(str);在使用迭代器遍历集合时,不能使用集合的方法增删元素,否则会引发异常
/*
* 迭代器提供了remove方法,用来删除通过next取出的元素
*/
it.remove();
}
System.out.println(str);
}
System.out.println(c);
7. 集合支持泛型,而泛型是用来约束集合中元素的类型
Collection<String> c=new ArrayList<String>();
//只能添加String类型的元素了
c.add("one");
c.add("two");
c.add("three");
c.add("four");
//c.add(1); //报错
//遍历集合元素
for(String str:c){//指定了集合是String类型
System.out.println(str);
}
/*
* 迭代器也应当指定泛型,而泛型的实际类型应当与它遍历的集合的泛型类型一致
*/
Iterator<String> it=c.iterator();
while(it.hasNext()){
//获取元素时不需要再造型了
String str=it.next();
System.out.println(str);
}
8. 集合转换为数组
Collection<String> c=new ArrayList<String>();
c.add("one");
c.add("two");
c.add("three");
c.add("four");
/*
* 集合提供了一个方法toArray,可以将当前集合转换为数组
*/
//Object[] array=c.toArray();返回的是一个Object类型,说明以后取元素还得挨着造型,不常用
/*
* 若给定的数组可用(数组可以存放集合中所有元素)时,则使用该数组
* 若不可用,会自动创建一个与给定数组同类型的数组
*/
String[] array=c.toArray(new String[c.size()]);
System.out.println("len:"+array.length);//len:4
for(String str:array){
System.out.println(str);
}
9. 数组转换为集合 需要注意,转换只能转换为List集合[只能转换为List集合的主要原因是:Set不能存放重复元素,所以若转换为Set集合可能出现丢失元素的情况]。使用的数组的工具类Arrays的静态方法asList
String[] array={"one","two","three","four"};
List<String> list=Arrays.asList(array);
/*
* 向集合中添加一个元素
* 以下做法会抛出异常的原因是:该集合是由数组转换过来的,那么该集合就表示原来的数组,
* 所以对集合的操作就是对数组的操作。那么添加元素会导致原数组扩容,就不能表示原来的数组了。
* 所以不允许向该集合添加新元素
*
*/
//list.add("five");
//System.out.println(list);//抛出异常
//修改集合元素,数组元素也会改变
list.set(1, "2");
System.out.println(list);//[one, 2, three, four]
for(String str:array){//输出数组元素
System.out.print(str+" ");//one 2 three four
}
System.out.println();
/*
* 若希望增删元素,需呀另创建一个集合
*/
//List<String> list1=new ArrayList<String>();
//list1.addAll(list);
/*
* 所有的集合都提供了一个带有Collection类型参数的构造方法。
* 该构造方法称为:复制构造器
* 作用是在创建当前集合的同时,集合中包含给定集合中的所有元素
*/
List<String> list1=new ArrayList<String>(list);//这一步代替以上两步
list1.add("five");
System.out.println(list1);//[one, 2, three, four, five]
10. java.util.List 可重复集,并且有序。特点是可以根据下标操作元素。常用实现类:ArrayList:使用数组实现,查询更快;LinkList:使用链表实现,增删更快(首尾增删效果明显)
public static void main(String[] args) {
/*
* E set(int index,E e)
* 将给定元素设置到指定位置上,返回值为原位置的元素。所以是替换元素操作
*/
List<String> list=new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
System.out.println(list);//[one, two, three, four]
String old=list.set(1, "2");
System.out.println(list);//[one, 2, three, four]
System.out.println("old:"+old);//old:two
//list.set(4, "five");这样做下标越界
/*
* E get(int index)
* 获取给定下标对应的元素
*/
String str=list.get(2);//获取第三个元素
System.out.println(str);//three
//传统循环遍历List集合
for(int i=0;i<list.size();i++){
str=list.get(i);
System.out.println(str);
}
}
11. List subList(int start,int end) 取子集, 获取当前集合中指定范围内的子集。同样含头不含尾
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
for(int i=0;i<10;i++){
list.add(i);
}
System.out.println(list);//[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
//获取3-7
List<Integer> subList=list.subList(3, 8);
System.out.println(subList);//[3, 4, 5, 6, 7]
//将子集中每个元素扩大十倍
for(int i=0;i<subList.size();i++){
//把subList里面每个元素都取出来再乘以10
subList.set(i, subList.get(i)*10);
}
System.out.println(subList);//[30, 40, 50, 60, 70]
//对子集的任何修改,就是修改原集合相应内容
System.out.println(list);//[0, 1, 2, 30, 40, 50, 60, 70, 8, 9]
//删除集合中2-8的元素
list.subList(2, 9).clear();
System.out.println(list);//[0, 1, 9]
}
12. List集合提供了一对重载的add,remove方法 void add(int index,E e) 将给定元素插入到指定位置;E remove(int index) 从集合中删除指定位置的元素,并将其返回。
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("one");
list.add("two");
list.add("three");
list.add("four");
System.out.println(list);//[one, two, three, four]
list.add(1, "2");
System.out.println(list);//[one, 2, two, three, four]
String old=list.remove(2);
System.out.println(list);//[one, 2, three, four]
System.out.println("old:"+old);//old:two
}
13. 增强for循环(又叫新循环 ) 新循环不能代替传统循环。作用仅仅是用来遍历集合或数组的。
public static void main(String[] args) {
String[] array={"one","two","three","four"};
//传统for循环
for(int i=0;i<array.length;i++){
String str=array[i];
System.out.print(str+" ");
}
System.out.println();
for(String str:array){
System.out.print(str+" ");
}
}
14. 新循环遍历集合
public static void main(String[] args) {
Collection c=new ArrayList();
c.add("one");
c.add("#");
c.add("two");
c.add("#");
c.add("three");
c.add("#");
c.add("four");
System.out.println(c);
/*
* 新循环并非新的语法,新循环是编译器认可,而不是虚拟机认可
* 使用新循环遍历集合时,编译器会将它改为迭代器方式的遍历。
* 所以在使用新循环遍历集合时,不能通过集合的方法增删元素
*/
for(Object o:c){//从集合里面取出来都是Object类型 ,所以冒号左边不是字符串
//以上的一语句相当于:Iterator it=c.iterator();
//while(it.hasNext()){
//Object o=it.next();
String str=(String)o;//强转
System.out.println(str);
if("#".equals(str)){
c.remove(str);//会出错
}
}
}
15. 排序集合元素 排序集合使用的是集合的工具类Collections的静态方法sort, 排序仅能对List集合进行。因为Set部分实现类是无序的
public static void main(String[] args) {
List<Integer> list=new ArrayList<Integer>();
Random random=new Random();
for(int i=0;i<10;i++){
list.add(random.nextInt(100));
}
System.out.println(list);//[42, 19, 50, 61, 2, 33, 79, 29, 14, 94]
/*
* 区别:
* Colletion是集合的接口
* Colletions是集合的工具类,它提供了很多方法。
*/
Collections.sort(list);//对集合进行自然排序,从小到大
System.out.println(list);//[4, 39, 61, 66, 75, 82, 87, 87, 91, 91]
}
16. 泛型泛型又称为参数化类型,是将当前类的属性的类型,方法参数的类型以及方法返回值的类型的定义权移交给使用者,使用者在创建当前类的同时将泛型的实际类型传入
public class Point<T> {
private T x;
private T y;
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
public Point(T x,T y){
super();
this.x=x;
this.y=y;
}
public String toString(){
return "("+x+","+y+")";
}
}
public class TestPoint {
public static void main(String[] args) {
Point<Integer> p1=new Point<Integer>(1,2);
p1.setX(2);
int x1=p1.getX();
System.out.println("x1:"+x1);
Point<Double> p2=new Point<Double>(1.1,2.2);
p2.setX(2.2);
double x2=p2.getX();
System.out.println("x2:"+x2);
Point<String> p3=new Point<String>("一","二");
p3.setX("二");
String x3=p3.getX();
System.out.println("x3:"+x3);
}
}
/**
* 泛型的原型是Object
* 定义了泛型只是编译器在做一些验证工作。当我们对泛型类型设置值时,会检查是否满足类型要求
* 当我们获取一个泛型类型的值时,会自动进行类型转换。
* @author xiaoxiannv
*
*/
public class TestPoint2 {
public static void main(String[] args) {
/*
* 这里指定泛型的实际类型是Integer
* 但实际上,创建的Point对象中,x,y属性是Object类型,这里只是应当将它当做Integer看待
*/
Point<Integer>p1=new Point<Integer>(1,2);
/*
* 由于参数是T,这里会验证实参是否为Integer,若不是,则编译失败!
* 可以传入基本类型,因为还会自动装箱
*/
p1.setX(1);
/*
* 获取时,也会自动进行造型。这里无需显示的进行类型转换
*/
int x1=p1.getX();
/*
* 若不指定泛型,则使用默认是Object类型
*/
Point p2=p1;
p2.setX("一");
String x2=(String)p2.getX();
System.out.println("x2:"+x2);
//类造型异常!
x1=p1.getX();
System.out.println("x1:"+x1);
}
}
17. java.util.Queue 队列 队列也可以存放一组元素,但是存取元素必须遵循:先进先出原则。
/*
* LinkedList也实现了队列接口。
* 因为它可以保存一组元素,并且首尾增删快。正好符合队列的特点
*/
Queue queue=new LinkedList<String>();
/*
* boolean offer(E e)
* 入队操作,向队尾追加一个新元素
*/
queue.offer("one");
queue.offer("two");
queue.offer("three");
queue.offer("four");
System.out.println(queue);//[one, two, three, four]
/*
* E poll()
* 出队操作,从队首获取元素,获取后该元素就从队列中被删除了。
*/
String str=(String) queue.poll();
System.out.println(str);//one
System.out.println(queue);//[two, three, four]
/*
* E peek()
* 引用队首元素,但是不做出队操作
*/
str=(String) queue.peek();
System.out.println(str);//two
System.out.println(queue);//[two, three, four]
System.out.println("size:"+queue.size());//size:3
//for(int i=0;i<queue.size();i++){size是变化的,这样遍历不对,因为不能遍历完所有元素
/*法1:for循环遍历
for(int i=queue.size();i>0;i--){
str=(String) queue.poll();
System.out.println("元素:"+str);
}*/
while(queue.size()>0){
str=(String) queue.poll();
System.out.println("元素:"+str);
}
System.out.println("遍历完毕");
System.out.println(queue);
18. 栈: 存储一组元素,但是存取元素必须遵循:先进后出原则。通常为了实现后退这类功能时会使用栈。
public static void main(String[] args) {
/*
* java.util.Deque
* 双端队列,两端都可以进出队。
* 当只调用从一端进出队操作时,就形成了栈结构
* 因此,双端队列为栈提供了两个方法
*/
Deque<String> stack=new LinkedList<String>();
/*
* void push(E e)
* 入栈操作,最后入栈的元素在栈顶(第一个元素位置)
*/
stack.push("one");
stack.push("two");
stack.push("three");
stack.push("four");
System.out.println(stack);//[four, three, two, one]
/*
* 出栈操作
* E pop()
*/
String str=stack.pop();
System.out.println(str);//four
System.out.println(stack);//[three, two, one]
str=stack.peek();
System.out.println(str);//three
System.out.println(stack);//[three, two, one]
//遍历
while(stack.size()>0){
str=stack.pop();
System.out.println(str);
}
System.out.println(stack);//[]
}
19. 排序自定义类型元素的集合
public class Point implements Comparable<Point>{
private int x;
private int y;
public Point(int x, int y) {
super();
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String toString(){
return "("+x+","+y+")";
}
/*
* 当实现了Comparable接口后,需要重写下面的方法。
* 该方法的作用是定义当前对象与给定参数对象比较大小的规则
* 返回值为一个int值,该值表示大小关系。它不关注具体的取值是多少,而关注的是取值范围
* 当返回值>0时:当前对象比参数对象大
* 当返回值<0时:当前对象比参数对象小
* 当返回值=0时:两个对象相等
*/
public int compareTo(Point o) {
/*
* 比较规则,点到原点的距离长的大
*/
int len=this.x*this.x+this.y*this.y;
int olen=o.x*o.x+o.y*o.y;
return len-olen;
}
}
public static void main(String[] args) {
List<Point> list=new ArrayList<Point>();
list.add(new Point(4,2));
list.add(new Point(2,3));
list.add(new Point(1,4));
list.add(new Point(6,7));
list.add(new Point(9,3));
list.add(new Point(8,1));
System.out.println(list);//[(4,2), (2,3), (1,4), (6,7), (9,3), (8,1)]
/*
* sort方法要求集合元素必须实现Comparable接口,该接口用于规定实现类是可以比较的。
* 其有一个抽象方法是用来定义比较大小的规则
*
* 我们想使用sort方法排序集合,但是该方法要求我们的集合元素必须实现Comparable接口并且定义比较规则,
* 这种我们想使用某个功能,而它要求我们修改程序的现象称为“侵入性”。
* 修改的代码越多,侵入性越强,越不利于程序的扩展
*/
Collections.sort(list);
System.out.println(list);//[(2,3), (1,4), (4,2), (8,1), (6,7), (9,3)]
}
public class SortListDemo2 {
public static void main(String[] args) {
List<String> list=new ArrayList<String>();
list.add("赵小龙老师");
list.add("李大拉拉老师");
list.add("王老师");
list.add("邓老师");
System.out.println(list);
MyComparator com=new MyComparator();
/*
* 重载的sort方法要求传入一个额外的比较器
* 该方法不再要求集合元素必须实现Comparable接口,并且也不再使用集合元素自身的比较规则排序了,
* 而是根据给定的这个额外的比较器的比较规则对集合元素进行排序。
* 实际开发中也推荐使用这种方式排序集合元素,若集合元素是自定义的
* 创建比较器时也推荐使用匿名内部类的形式
*/
Collections.sort(list,com);
System.out.println(list);//[王老师, 邓老师, 赵小龙老师, 李大拉拉老师]
//匿名内部类形式创建
Comparator<String> com1=new Comparator<String>() {
public int compare(String o1,String o2){
return o2.length()-o1.length();//字符串中,字符少的越大
}
};
Collections.sort(list,com1);
System.out.println(list);//[李大拉拉老师, 赵小龙老师, 王老师, 邓老师]
}
}
/*
* 定义一个额外的比较器
*/
class MyComparator implements Comparator<String>{
/*
* 该方法用来定义o1和o2的比较
* 若返回值大于0:o1>o2
* 若返回值小于0:o1<o2
* 若返回值等于0:两个对象相等
*/
public int compare(String o1,String o2){
/*
* 字符串中 字符多的大
*/
return o1.length()-o2.length();
}
}