Java基础-集合

来源:互联网 发布:剑灵大地力士卡刀数据 编辑:程序博客网 时间:2024/05/16 12:25


一.集合的组成及概念


为什么出现集合类?

面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储,集合就是存储对象最常用的一种方式。

数组和集合类同时容器,有何不同?

数组虽然也可以存储对象,但是长度固定,集合长度是可变的。

数组中可以存储基本数据类型,集合只能存储对象。

集合类的特点

集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象。


二.Collection

1.collection  //2

(1).collection的组成    //3

List:元素是有序的,元素可以重复。因为该集合体系有索引。

set:元素是无序,元素不可以重复。

(2)演示collection的共性方法     //3

共性方法

1.add
2.获取个数。集合长度。
sop("size:"+a1.size());
打印集合
sop(a1); //这样就可以打印集合中所有元素
3.删除元素
清空集合
a1.clear();
4.判断元素(是否包含其他元素,或者是否为空)
sop("java03是否存在:"+a1.contains("java03"));
sop("集合是否为空?"+a1.isEmpty());

(3)迭代器(Iterator)

什么是迭代器呢?

a1.remove("java02");

sop(a1);

其实就是集合的取出元素的方式。


可以这么理解   容器就是一个大罐子    里面的对象就是罐子里的布娃娃  

迭代器就是抓娃娃的爪子    要抓娃娃爪子要移动  松开   抓紧之类的各种状态

(4)代码实例

import java.util.*;class CollectionDemoText{public static void main(String[] args){method_get_size();}public static void sop(Object obj){System.out.println(obj);}public static void method_get_size(){ArrayList a11 = new ArrayList();a11.add("java01");a11.add("java02");a11.add("java03");a11.add("java04");sop(a11);//打印所有元素ArrayList a12 = new ArrayList();a12.add("java011");a12.add("java021");a12.add("java031");a12.add("java041");a12.add("java01");sop(a12);//打印所有元素//演示集合中是否为空,是否包含某一元素操作sop("a12是否为空--"+a12.isEmpty());sop("a12是否包含java01--"+a12.contains("java01"));sop("a12是否包含java03--"+a12.contains("java03"));//演示通过迭代器获取集合元素操作Iterator t1 = a11.iterator();sop("下面获取集合中的元素");while(t1.hasNext()){sop(t1.next());}//演示获取集合长度操作sop("下面打印集合的长度");sop("集合长度是----"+a11.size());//演示获取相同元素操作//sop("下面是两个集合共有的元素");//a11.retainAll(a12);//sop(a11);//演示删除操作sop("下面删除元素");a11.remove("java01");sop(a11);//演示清空操作sop("下面清空集合");sop("集合a12"+a12);sop("开始清空");a12.clear();sop("集合a12"+a12);}}

注意:!!!!!

retainall返回的是true(有相同),false(无相同)
然后改变了调用集合的元素,只保留了相同的元素!!!!


2.List

List:(元素都带着脚表)

(1)特有方法。凡是可以操作角标的方法都是该体系特有的方法。

1.增

add(index,element);
addAll(index,collection);  //从指定的位置开始,将指定 collection 中的所有元素插入到此列表中

2.删

remove(index);

3.改

set(index,element);

4.查

get(index);
subList(from,to);
ListIterator();!!!




(2)代码实例


import java.util.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){arrayList_method();}public static void  arrayList_method(){ArrayList a11 =new ArrayList();a11.add("java01");a11.add("java02");a11.add("java03");a11.add("java04");sop("打印所有元素");sop(a11);//打印所有元素//在指定位置添加新元素 add(int index ,E element)//sop("在指定位置添加了新元素");//a11.add(2,"java99");//sop(a11);  //打印[java01,java02,java99,java03,java04],集合长度自动增加//删除指定的元素//sop("删除指定位置的元素");//a11.remove(4);//sop(a11);  //打印[java01,java02,java99,java03]//修改指定位置的元素//sop("修改指定位置的元素");//a11.set(2,"java007");//sop(a11);//通过角标获取元素//sop("获取指定位置的元素");//sop("get(1):"+a11.get(1));//sop(a11);//使用子迭代器listIterator//sop("使用迭代器");//ListIterator li = a11.listIterator();  //注意写法!!!大小写的区别//while(li.hasNext())//{//****************************************************************************************//Object obj = li.next();///-----java01-----java02----java03----java04---//    ||   |    |      |//    |(1)|(2)   |(3)    |(4)      |(5)//当程序跑完ListIterator li = a11.listIterator();迭代器的位置在1处!!!// 当执行it.next(),就跑到(2)处//Iterator迭代器包含的方法有:///hasNext():如果迭代器指向位置后面还有元素,则返回 true,否则返回false//next():返回集合中Iterator指向位置后面的元素//remove():从迭代器指向的 collection 中移除迭代器返回的最后一个元素(可选操作)。每次调用 next 只能调用一次此方法。//ListIterator迭代器包含的方法有://add(E e): 将指定的元素插入列表,插入位置为迭代器当前位置之前//hasNext():以正向遍历列表时,如果列表迭代器后面还有元素,则返回 true,否则返回false//hasPrevious():如果以逆向遍历列表,列表迭代器前面还有元素,则返回 true,否则返回false//next():返回列表中ListIterator指向位置后面的元素//nextIndex():返回列表中ListIterator所需位置后面元素的索引//previous():返回列表中ListIterator指向位置前面的元素//previousIndex():返回列表中ListIterator所需位置前面元素的索引//remove():从列表中移除由 next 或 previous 返回的最后一个元素(可选操作)。对于每个 next 或 previous 调用,//只能执行一次此调用。只有在最后一次调用 next 或 previous 之后,尚未调用 ListIterator.add 时才可以执行该调用。//set(E e):从列表中将next()或previous()返回的最后一个元素返回的最后一个元素更改为指定元素e//************************************************************************//if(obj.equals("java02"))///{//sop(li);////Iterator的子迭代器可以添加元素//li.add("java88");  //为什么是在java02后面添加元素,而不是在java04?????????上面有讲///}//因为迭代器的列表中这时候只有[java01,java02]  还是要看看!!!!//}//sop(a11);//[java01,java02,java88,java03,java04]//使用父类迭代器,注意删除!!!//sop("使用父类迭代器");//sop(a11);//Iterator it = a11.iterator();//while(it.hasNext())//{//Object obj = it.next();//if(obj.equals("java03"))//{//it.remove();   //为什么删的是当前元素!!!??????上面讲了,看一看//}//sop("OBJ--"+obj);//打印  OBJ--java01  OBJ--java02  OBJ--java03  OBJ--java04////因为移出只是引用被移除了,但是元素还是在内存中依然被obj使用。所以打印出来了//局部变量//}//sop(a11); //[java01,java02,java04],因为已经被移除了}}

(3)List的组成(元素是有序的,元素可以重复。因为该集合体系有索引。) //3

  ArrayList:

  底层的数据结构使用的是数组结构。特点:查询速度很快,但是增删稍慢(因为要移位,元素多才能体现出来)。线程不同步(可变长度数组,开始默认容量为10,如果超过则增加百分之五十变成15.
A--->B---->C---D

  LinkedList:

  底层使用的链表数据结构。特点:增删速度很快(因为只要改动部分,比如BC之间加个E,只要B知道EE知道C就可以了),查询稍慢(因为一个一个关联,依次往下问)。

  Vector:(但是现在不用了)

  底层是数组数据结构,线程同步(如果多线程也不用这个)。特点:增删查找都慢。ArrayList替代了(可变长度数组,开始默认容量为10,如果超过则增加百分之100,变成20,有点浪费.
  淘汰原因

枚举就是vector特有的取出方式。

发现枚举和迭代器很像。

其实枚举和迭代是一样的。

因为枚举的名称以及方法的名称都过长。

所以被迭代器取代了。

枚举郁郁而终了。


class VectorDemo{public static void main(String[] args){Vector v = new Vector();v.add(“java01”);v.add(“java02”);v.add(“java03”);v.add(“java04”);Enumeration en = v.elements();while(en.hasMoreElements()){system.out.println(en.nextElement());}}}

(4)ArrayList   //3


1.ArrayList练习1 //4

需求:取出arrayList集合中的重复元素
arraylist或者linklist中的contain和remove用的都是equalsimport java.util.*;class CollectionDemoText{public static void main(String[] args){ArrayList a1 = new ArrayList();a1.add("java01");a1.add("java02");a1.add("java03");a1.add("java04");a1.add("java02");a1.add("java01");a1.add("java06");sop("原始集合");sop(a1);sop("取出相同的元素");a1 = removeSameElements(a1);sop("现在的集合");sop(a1);}public static void sop(Object obj){System.out.println(obj);}public static  ArrayList removeSameElements(ArrayList a2){ArrayList newa1 = new ArrayList();Iterator it = a2.iterator();while(it.hasNext()){Object obj = it.next();if(!newa1.contains(obj)){newa1.add(obj);}}//**************************************************************//开始没有使用临时容器,就靠迭代器迭代然后添加//ListIterator it = a2.listIterator();//while(it.hasNext())//{//Object obj = it.next();  //sop("1");//if(!a2.contains(obj))   //如果这么写永远也进不了if内,因为永远包括obj//{//sop("2");//it.add("java22");//}//}//return a2;//****************************************************************return newa1;}}



2.ArrayList 练习2

需求:将自定义对象作为元素存到ArrayList集合中,并取出重复元素。
比如:存人对象。同姓名同年龄,视为同一个人
//思路://1.对人描述,将数据封装进入对象//2.定义容器,将人存入。//3.取出import java.util.*;class  Person{private String name;private int age;Person(String name,int age){this.name = name;this.age = age;}//弄清一下为什么事在person里面复写???因为add里面的元素都是person类的public boolean  equals(Object obj){if(!(obj instanceof Person))return false;Person p = (Person)obj ;System.out.println("p姓名:"+p.name+"p年龄 :"+p.age);System.out.println("姓名:"+this.name+"年龄:"+this.age);//String类复写了equalsif((this.name.equals(p.name))&&(this.age == p.age)){System.out.println("true");return true;}else{System.out.println("false");return false;}}public String getName(){return name;}public int getAge(){return age;}}class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){ArrayList  a1 = new ArrayList();a1.add(new Person("daxiong",14));a1.add(new Person("daxiong1",16));a1.add(new Person("daxiong2",17));a1.add(new Person("daxiong3",14));a1.add(new Person("daxiong",16));a1.add(new Person("daxiong",14));a1.add(new Person("daxiong2",18));a1.add(new Person("daxiong3",17));a1 = removeSameElements(a1);//打印集合中的元素Iterator it2 = a1.iterator();while(it2.hasNext()){Person p = (Person)it2.next();sop(p.getName()+"::"+p.getAge());}//打印机集合中的元素sop("remove daxiong3"+a1.remove(new Person("daxiong3",14)));}public static  ArrayList removeSameElements(ArrayList a2){ArrayList newa1 = new ArrayList();Iterator it = a2.iterator();while(it.hasNext()){Object obj = it.next();if(!newa1.contains(obj)){sop("add");newa1.add(obj);}}return newa1;}}


(5)LinkList  //3

LinkedList:特有方法: //4

1.老的特有方法    //5
addFirst();
addLast();

getFirst();
getLast();
获取元素,但不删除元素。如果集合中没有元素,会出现NoSuchElementsException

removeFirst();
removeLast();
获取元素,但是元素被删除,如果集合中没有元素,会出现NoSuchElementsException


2.在JDK1.6出现了替代方法
offerFirst();
offerLast();

peekFirst();
peekLast(); 
获取元素,但不删除元素。如果集合中没有元素,会返回null

pollFirst();
pollLast();
获取元素,但是元素被删除,如果集合中没有元素,会返回null

3.代码实例
import java.util.*;class CollectionDemoText{public static void main(String[] args){methodText();}public static void sop(Object obj){System.out.println(obj);}public static void methodText(){LinkedList a11 = new LinkedList();//倒序打印a11.offerFirst("java01");a11.offerFirst("java02");a11.offerFirst("java03");a11.offerFirst("java04");sop(a11);  //打印出[java04,java03,java02,java01]//正序打印a11.offerLast("java05");a11.offerLast("java06");a11.offerLast("java07");a11.offerLast("java08");sop(a11);//打印出[java04,java03,java02,java01,java05,java06,java07,java08]//获取头尾元素//sop(a11.peekFirst());//sop(a11.peekLast());//删除元素并取出sop("删除元素并取出");while(!a11.isEmpty()){sop(a11.pollLast());}sop("现在集合中的元素");sop(a11);  //因为删光了}}






(2)linkedlist小练习  //4

需求:使用LinkedList模拟一个堆栈或者队列数据结构
堆栈:先进后出  如同一个杯子
队列:先进先出  First in First out FIFO 如同一个水管
import java.util.*;


class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){Duilie_Duizhan a1= new Duilie_Duizhan();a1.myAdd("java01");a1.myAdd("java02");a1.myAdd("java03");a1.myAdd("java04");while(!a1.nullOrNot()){//sop(a1.duiLieGet());sop(a1.duiZhanGet());}}}class Duilie_Duizhan{private LinkedList lk;Duilie_Duizhan(){lk = new LinkedList();}public void myAdd(Object obj){lk.offerFirst(obj);}public Object duiZhanGet(){return lk.pollFirst();}public Object duiLieGet(){return lk.pollLast();}public boolean nullOrNot(){return lk.isEmpty();}}

(6)总结

如果增删操作比较多就用linklist
设计增删但不频繁  linklist arraylist
如果还涉及到查找  用arraylist
如果实在不知道用什么就用arraylist


3.Set   //2

  (1)Set的组成(元素是无序(存入和取出的顺序不一定一致),元素不可以重复)   //3

1.HashSet:底层数据结构是哈希表。

HashSet是如何保证元素唯一性的呢?

是通过元素的两个方法,hashcode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true.
如果元素的hashcode值不同,不会调用equals.


 2.Treeset: //4

底层数据结构是二叉树。
保证元素唯一性的依据。

TreeSet是如何保证元素唯一性的呢?
(1)Treeset排序的第一种方式,让元素自身具备比较性

元素需要实现compareable接口,覆盖compareTo方法。

这种房也成为元素的自然排序,或者叫做默认顺序。

(2)TreeSet的第二种排序方式。

当元素自身不具备比较性时,或者具备的比较性不是所需要的。

集合需要实现compartor接口 ,然后覆盖compare方法 


注意:对于判断元素是否存在,以及删除等操作,依赖的方法元素的hashcodeequals方法,先判断hascode,再用equals(arraylist   lisnklist  都是用equals判断),这是数据结构的问题

   (2).HashSet   //3

1.代码实现

import java.util.*;class Demo{}class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){Demo d1 = new Demo();Demo d2 = new Demo();//这个地方再看看sop,到底打印什么了??????<p><span style="white-space:pre"></span>//两个对象的内存地址,存的顺序不一定是放的顺序,取是按表(按哈希值存)的顺序来存,也可以自定义值</p><p> <span style="white-space:pre"></span>//Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于: <span style="white-space:pre"></span>//getClass().getName() + '@' + Integer.toHexString(hashCode())</p>sop(d1);  //会打印出哈希值,其实就是toString,然后toString中的hashcodesop(d2);  //会打印出哈希值//地址HashSet hs = new HashSet();sop(hs.add("java01"));  //truesop(hs.add("java01"));//false//地址值一样,内容也一样hs.add("java02");hs.add("java03");hs.add("java04");hs.add("java05");Iterator it = hs.iterator();while(it.hasNext()){sop(it.next()); //打印出来是无序的}}}

2.练习  //4

需求:往hashset集合中存入自定义对象姓名和年龄相同为同一个人,重复元素
import java.util.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){HashSet hs = new HashSet();hs.add(new Person("java01",13));hs.add(new Person("java02",14));hs.add(new Person("java03",15));hs.add(new Person("java01",13));hs.add(new Person("java01",14));hs.add(new Person("java02",17));Iterator it = hs.iterator();while(it.hasNext()){Person p = (Person)it.next();//迭代器的取出的对象才能强制转换成Personsop("-名字-"+p.getName()+"-年龄-"+p.getAge());}}}class Person{private String name;private int age;Person(String name, int age){this.name = name;this.age = age;}public int hashCode()  //自定义哈希值{System.out.println(this.name+"....hashCode");return age*2+this.name.hashCode();//<span style="font-family: 宋体;">随便写的,也可用</span><span style="font-family: 'Times New Roman';">/name.hashcode()*age</span><span style="font-family: 宋体;">但是怕超出范围,这么写的是为了保持哈希值唯一性</span>}<span style="white-space:pre"></span><p><span style="white-space:pre"></span>//<span style="font-family:宋体;">在哈希表里先看哈希值</span></p>public boolean equals(Object obj){if(!(obj instanceof Person))return false;Person p = (Person)obj;System.out.println(this.name+"..equals.."+p.name);if((this.name == p.name)&&(this.age == age)){return true;}else{return false;}}public String getName(){return name;}public int getAge(){return age;}}


(3)TreeSet   //3

   1.TreeSet基本特性

底层数据结构是二叉树。
保证元素唯一性的依据。

TreeSet是如何保证元素唯一性的呢?
(1)Treeset排序的第一种方式,让元素自身具备比较性
(2)TreeSet的第二种排序方式。

元素需要实现compareable接口,覆盖compareTo方法。

这种房也成为元素的自然排序,或者叫做默认顺序。

当元素自身不具备比较性时,或者具备的比较性不是所需要的。

集合需要实现compartor接口 ,然后覆盖compare方法 


2.练习1    //4

需求:往Treeset集合中存储自定义对象学生。想按照学生的年龄进行排序。记住排序时,当主要条件相同时,一定判断一下次要条件


第一种 让元素具备可比性

import java.util.*;//import java.lang.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){TreeSet a1 = new TreeSet();a1.add(new Student("java01",13)); //需要具备比较性蓝色字体,//否则,传两个进来就报错,一个不会(因为不用排序)a1.add(new Student("java02",14));a1.add(new Student("java03",13));a1.add(new Student("java01",13));a1.add(new Student("java01",17));Iterator it = a1.iterator();<p><span style="white-space:pre"></span>/<span style="font-family:宋体;">明明只把</span><span style="font-family:Times New Roman;">age</span><span style="font-family:宋体;">跟</span><span style="font-family:Times New Roman;">name</span><span style="font-family:宋体;">排序,为什么就自动从小到大排序????下面的原理图!!!!!!!!!!</span></p><p></p>while(it.hasNext()){Student s2 = (Student)it.next();sop("-名字-"+s2.getName()+"年龄"+s2.getAge());//-名字-java01年龄13//-名字-java03年龄13//-名字-java02年龄14//-名字-java01年龄17}}}class Student implements Comparable{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;}public int compareTo(Object obj){
</pre><pre name="code" class="java">
<p><span style="white-space:pre"></span>//return 1; //<span style="font-family:宋体;">也就是说下一个元素比上一个大</span></p><p><span style="white-space:pre"></span>//return -1;//<span style="font-family:宋体;">也就是说下一个元素比上一个小</span></p><p>//return 0;//<span style="font-family:宋体;">也就是说下一个元素等于上一个元素</span></p>if(!(obj instanceof Student)){throw new RuntimeException("不是学生对象");}Student s1 = (Student)obj;if(this.age > s1.age){return 1;}else if(this.age <s1.age){return -1;}else {//String 方法有compareTo这个方法//ask码值大的就返回1,排后面面//-1排前面面//-名字-java01年龄13//-名字-java03年龄13//-名字-java02年龄14//-名字-java01年龄17returnthis.name.compareTo(s1.name);}}}

/明明只把agename排序,为什么就自动从小到大排序????下面的原理图


treeset底层结构是二叉树,之前回说为什么只是做了比较,但是却没排序却自动排序了,试音,return 1  return 0  return -1的原因,自动把小的那边放到左边(例如  20放到22的左下角),还有下面(例如,左下角有两个19,但是08小于09,所以就放他的左下角)




第二种让集合具备可比性.
当元素自身不具备比较性,或者具备的比较性不是所需要的。
这时需要让容器自身具备比较性。
定义了比较器,将比较器对象作为参数传递给TreeSet集合的构造函数


当两种排序都存在时,以比较器为主。
定义了一个类,实现conparator接口,覆盖compare方法(接口在treeset构造函数中)


import java.util.*;//import java.lang.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){TreeSet a1 = new TreeSet(new MyCompare());a1.add(new Student("java01",13)); //需要具备比较性蓝色字体,//否则,传两个进来就报错,一个不会(因为不用排序)a1.add(new Student("java02",14));a1.add(new Student("java03",13));a1.add(new Student("java01",13));a1.add(new Student("java01",17));Iterator it = a1.iterator();while(it.hasNext()){Student s2 = (Student)it.next();sop("-名字-"+s2.getName()+"年龄"+s2.getAge());//-名字-java01年龄13//-名字-java03年龄13//-名字-java02年龄14//-名字-java01年龄17}}}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 MyCompare implements Comparator{public int compare(Object obj1, Object obj2){Student s1 = (Student)obj1;Student s2 = (Student)obj2;int num = s1.getName().compareTo(s2.getName());if(num == 0){<span style="white-space:pre"></span><p></p><p><span style="white-space:pre"></span>//<span style="font-family:宋体;">为什么要用</span><span style="font-family:Times New Roman;">integer</span><span style="font-family:宋体;">,让他变成对象是为什么???是不是</span><span style="font-family:Times New Roman;">compareTo</span><span style="font-family:宋体;">的参数就是需要对象????对的 !!!!!</span></p><p><span style="white-space:pre"></span>//<span style="font-family:宋体;">因为</span><span style="font-family:Times New Roman;">name </span><span style="font-family:宋体;">是</span><span style="font-family:Times New Roman;">String</span><span style="font-family:宋体;">类对象</span></p> return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));}return num;}}

3.练习2   //4

需求:按照字符串长度排序。字符串本身具备比较性。但是他的比较方式不是所需要的。这时就只能使用比较器。
import  java.util.*;class CollectionDemoText{public static void main(String[] args){TreeSet ts = new TreeSet(new StrLenComparator());ts.add("abcd");ts.add("cc");ts.add("cba");ts.add("hahaha");ts.add("abc");Iterator it = ts.iterator();while(it.hasNext()){System.out.println(it.next());}}}class StrLenComparator implements Comparator{public int compare(Object o1,Object o2){String  s1 = (String)o1;String  s2 = (String)o2;int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));if(num == 0){return  s1.compareTo(s2); //长度相同,判断内容是否相同  //String 其实继承了compareable这个接口,然后写了compareTo这个方法  //,例如 ac  ab,字符少的放前面顺序就是  ab  ac就是Ask码值相减}returnnum;}}

泛型   //2

1.泛型:JDK1.5版本以后出现新特性,用于解决安全问题,是一个类型安全机制。

2.使用泛型的好处

1.将运行时期出现问题classcastException,转移到了编译时期,
方便于程序员解决问题,让运行事情问题减少,安全。
2.避免强制转换麻烦。

3.泛型格式:通过<>来定义遥操作的引用数据类型。

4.什么时候使用泛型?

通常在集合框架中很常见。
只要见到<>就要定义泛型(在API中可以看到例如arraylist<E>)
其实<>就是用来接收类型的。

当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可

5.老版

class GenericDemo{public static void main(String[] args){ArrayList  al = new ArrayList(); //没有明确数据类型,所以引起安全隐患//ArrayList<String> a1 = new ArrayList<String>();//2这种是安全的al.add(“abc01”);al.add(“abc0991”);al.add(“abc014”);al.add(4);//al.add(new Interger(4));//在这里会引起运行报错,因为不能把 Interger(4)转换为string//把数据取到迭代器中2Iterator<String> it = al.interator();//明确了迭代器中的数据类型while(it.hasNext()){//String s = (string)it.next();//length是String特有的方法,所以强转String s = it.next();//写了代码2  就不用强转System.out.println(s+”:”+s.length());}}}


6.新版

class GenericDemo{public static void main(String[] args){ArrayList<String> al = new ArrayList<String>();//定义一个arraylist容器,里面的元素是string型,指定类型为Stringal.add(“abc01”);al.add(“abc0991”);al.add(“abc014”);//al.add(4);//al.add(new Interger(4));Iterator<String> it = al.interator();//将数据取到迭代器,所以也必须说明迭代器也是string型的??????? 知道了,如果不这么做下面就要写成String s = (string)it.next();while(it.hasNext()){String s = it.next();System.out.println(s+”:”+s.length());}}}

7.泛型的使用

import java.util.*;class GenericDemo2{    public static void main(String[] args)  {<span style="white-space:pre"></span>TreeSet<String> ts = new TreeSet<String>(new LenComparator());<span style="white-space:pre"></span>ts.add(“abcd”);<span style="white-space:pre"></span>ts.add(“cc”);<span style="white-space:pre"></span>ts.add(“cba”);<span style="white-space:pre"></span>ts.add(“aaa”);<span style="white-space:pre"></span>ts.add(“z”);<span style="white-space:pre"></span>ts.add(“hahaha”);<span style="white-space:pre"></span>Iterator<String> it = ts.iterator();<span style="white-space:pre"></span>while(it.hasNext())<span style="white-space:pre"></span>{<span style="white-space:pre"></span>String s = it.next();<span style="white-space:pre"></span>System.out.println(s); <span style="white-space:pre"></span>       //打印aaa <span style="white-space:pre"></span>abcd <span style="white-space:pre"></span>cba<span style="white-space:pre"></span> cc<span style="white-space:pre"></span> hahaha<span style="white-space:pre"></span> z<span style="white-space:pre"></span>为了能够按字符长度打印,所以下面写了个比较的函数   }}}class LenComparator Implements Comparator<String>//有的没有参数(只有<>),不能写<>!!!一定要使用强转(代码3),有参数的叫泛型类 //没看懂???????????看懂了,compartor写了<String>,后面就不需要写代码3{<span style="white-space:pre"></span>  public int compare(String o1,String o2)<span style="white-space:pre"></span>{<span style="white-space:pre"></span>//String s1 = (String)o1; // 代码3<span style="white-space:pre"></span>//String s2 = (String)o2;<span style="white-space:pre"></span>int num  = new Interger(o2.length()).compareTo(new Interger(o1.length()));<span style="white-space:pre"></span>if(num == 0)<span style="white-space:pre"></span>return  o2.compareTo(o1);<span style="white-space:pre"></span>return num;<span style="white-space:pre"></span>}}

8.泛型类


class Worker{}class student{}class Tool   //通用性不好,每创建一个类都得重写一个{private Worker w;public void setWorker(Worker w)      {this.w = w;}public Worker getWorker(){return w;}}


1泛型前做法

class Tool   //通用性很好{private Object obj;public void setObject (Object  obj){this.obj= obj;}public Object setObject (){return obj;}}


2.泛型后做法

什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候
早期定义object来完成扩展。
现在定义泛型来完成扩展
class Utils<QQ>{private QQ q;public void setObject(QQ q){this.q = q;}public QQ getobject(){return q;}}


class GenericDemo3{public static void main(String[] args){//泛型前     //看的不是很明白?????看明白了//Tool t = new Tool();//t.setObject (new Worker()); //这里如果new student()编译不会报错,因为是用objext来接收的//Worker w = (Worker)t.getObject();//泛型后Utils<Worker> u = new Utils<Worker>();U.setObject(new Worker());    //如果改成 new student();会在编译过程中报错,这就是使用泛型的好处,如果没用可能会在执行过程中报错Worker   w = u.getObject();}}

三.Map

1.共性方法  //2

Map<K,V>

K-此映射所维护的键的类型

V-映射值的类型


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()

value()

entrySet()

keySet()

5.代码实现  //3

1.

import java.util.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){Map<String,String> ha = new HashMap<String , String>();sop("put1-"+ha.put("01","dx1"));//打印null,因为会返回与key关联的旧值,如果key没有任何映射关系,则返回Nullsop("put1-"+ha.put("01","dx2"));//打印dx1ha.put("03","dx1");ha.put("04","dx1");ha.put("05","dx7");sop(ha);sop("是否包含023这个键-"+ha.containsKey("023"));//打印falsesop("是否包含dx4这个值-"+ha.containsValue("dx4"));//打印falsesop("是否包含01这个键-"+ha.containsKey("01"));//打印falsesop("是否包含dx2这个值-"+ha.containsValue("dx2"));//打印falsesop("移出键07-"+ha.remove("07"));//返回与key关联的旧值,不存在就返回nullsop("移出键05-"+ha.remove("05"));//dx7ha.put("06",null);//这么写但是多大没意义sop("获取键06的值"+ha.get("o6"));//指定键所映射的值;如果此映射不包含该键的映射关系,则返回 nullsop("获取键04的值"+ha.get("04"));//获取map集合中所有的值Collection<String> coll = ha.values();//values返回此映射中包含的值的 collection 视图sop(coll);  //[dx2,dx1,dx1,null]sop(ha);//{01 = dx2,03 = dx1, 04 = dx1 , 06 = null}}}

2.keySet(),entrySet()  //4

get只能获取对应的一个键值,能不能获取很多键值,这就是写这个的原因

1.Set <k>keyset:将map中所有的键存入到set集合。因为set具备迭代器。
所有可以迭代方式取出所有的键,在根据get方法。获取每个键对应的值。
原理:map集合的取出原理:将map集合转成set集合。在通过迭代器取出。
2.Set<Map.entry<k,v>> entrySet: 将map集合中的映射关系存入到了set1集合中,而这个关系的数据类型就是:  Map.Entry
1.key取值方式

2.mapentry获取键值原理

import java.util.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){Map<String,String> ma = new HashMap<String,String>();ma.put("02","dx1");ma.put("02","dx2");ma.put("03","dx3");ma.put("04","dx4");ma.put("05","dx5");ma.put("06","dx1");//使用keySet迭代取值//Set<String> s1 = ma.keySet();//返回此映射中所包含的键(!!!!!)的 Set 视图//Iterator<String> it = s1.iterator();//while(it.hasNext())//{//String key = it.next();//String value = ma.get(key);//sop("key"+key+"-value-"+value);////sop(it.next()+"对应的值"+ma.get(it.next()));//这样调用会出现noSuchElements<span style="white-space:pre"></span>//因为会调用到06的时候已经是最后一个值了,再来个it.next(),就没值了,//就会抛出noSuchElements(没有元素可以迭代)//}//使用entrySet迭代取值Set<Map.Entry<String,String>> e1 = ma.entrySet();//返回此映射所包含的映射关系(也就是<Map.entry<String,String>!!!!)的 Set 视图Iterator<Map.Entry<String,String>> it2 = e1.iterator();while(it2.hasNext()){Map.Entry<String,String> ma1 = it2.next();String key = ma1.getKey();String value = ma1.getValue();sop("key"+key+"-value-"+value);}}}//map.entry  其实entry也是一个借口,他是map借口中的一个内部接口interface Map    //有map集合才能有entry(代表映射关系)关系,可以说是map集合的内部事物,可以直接访问map集合的内部元素,所以才定义在内部,能加
<span style="white-space:pre"></span>//static的接口<span style="white-space:pre"></span>一般都是内部接口!!!!!!!,因为只有接口在成员位置上才能加静态修饰符???(这个不太明白){public static interface entry{public abstract Object getkey();public abstract Object getvalue();}}class HashMap  implements map.Entry  //内部类来实现entry,外部类实现map{class haha implements Map.entry{public Object getkey(){}public Object getvalue(){}}}


2.Map的组成   //2


Hashtable:底层是哈希表数据结构,不可以存入nullnull值。该集合是线程同步的。jdk1.0

HashMap:底层是哈希表数据结构,允许存入nullnull值。该集合是线程不同步的。jdk1.2

Treemap底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。

注意:set很像,其实大家。set底层就是使用了map集合!!!!!!!

(1)TreeMap练习1   //3

需求:对学生对象的年龄进行升序排序。

因为数据是以键值对形式存在的。
所以要使用可以排序的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 String getName(){return name;}public int getAge(){return age;}public int hashCode(){return age*2+name.hashCode(); //String类型有hashcode}public boolean equals(Object obj){if(!(obj instanceof Student)){throw new ClassCastException("类型不匹配");}Student  p = (Student)obj;return ((this.name.equals(p.name)) && ((this.age == p.age)));//可不可以采用this.name.compareTo(p.name)//equals返回的是正负}public int compareTo(Student s1)  //注意复写,要把参数类型也要复写,如果写Student s1会报错  //因为没写Comparable<Student>,所以只能写conpareTO(Object obj){//if(!(obj instanceof Student))//{//throw new ClassCastException("比对类型不匹配")//}//按照年龄排序******************************************************************************int num = (new Integer(s1.age)).compareTo(new Integer(this.age));if(num == 0){return this.name.compareTo(s1.name); //返回的是1 , 0 , -1}else{return num;}//*******************************************************************************************//按照名字排序**************************************int num = s1.name.compareTo(this.name);if(num == 0){return (new Integer(s1.age)).compareTo(new Integer(this.age));}else{return num;}//*****************************************************}}class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){//记住只有TreeMap才能排序!!!!!!!TreeMap<Student , String> ma = new TreeMap<Student , String>();ma.put(new Student("dx1",111),"beijing");ma.put(new Student("dx1",111),"tianjing");ma.put(new Student("dx2",13),"beijing");ma.put(new Student("dx3",45),"jiangxi");ma.put(new Student("dx5",52),"guangdong");ma.put(new Student("dx6",11),"fujian");sop(ma);//用keySet取值sop("keySet.set取值排列入下");Set<Student> keyset = ma.keySet();Iterator<Student> it = keyset.iterator();//Iterator <Student> it =keySet.iterator();while(it.hasNext()){Student key = it.next();String value = ma.get(key);sop("学生:"+key.getName()+"年龄:"+key.getAge()+"地址:"+value);}//用entry.Set取值sop("ENtry.set取值排列入下");Set<Map.Entry<Student , String >> entryset = ma.entrySet();Iterator<Map.Entry<Student , String >> it1 = entryset.iterator();//Iterator<Map.Entry<Student , String >> it = entrySet.iterator();while(it1.hasNext()){Map.Entry<Student , String > ma1 = it1.next();Student key = ma1.getKey();String value = ma1.getValue();sop("学生:"+key.getName()+"年龄:"+key.getAge()+"地址:"+value);}}}




方法二  让集合具有比较性,用比较器比较


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;}public int hashCode(){return age*2+name.hashCode(); //String类型有hashcode}public boolean equals(Object obj){if(!(obj instanceof Student)){throw new ClassCastException("类型不匹配");}Student  p = (Student)obj;return ((this.name.equals(p.name)) && ((this.age == p.age)));//可不可以采用this.name.compareTo(p.name)//equals返回的是正负}}class MyCompare implements Comparator<Student>{public int compare(Student s1 ,Student s2){//按照年龄排序**********************************if(s1.getAge()>s2.getAge()){return -1;}elseif(s1.getAge()<s2.getAge()){return 1;}else{return s1.getName().compareTo(s2.getName());}//************************************************//按照名字排序*********************************int num = s1.getName().compareTo(s2.getName());if(num == 0){return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));}else{return num;}//按照名字排序*********************************}}class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){TreeMap<Student , String> ma = new TreeMap<Student , String>(new MyCompare());ma.put(new Student("dx1",111),"beijing");ma.put(new Student("dx1",111),"tianjing");ma.put(new Student("dx2",13),"beijing");ma.put(new Student("dx3",45),"jiangxi");ma.put(new Student("dx5",52),"guangdong");ma.put(new Student("dx6",11),"fujian");sop(ma);//用keySet取值sop("keySet.set取值排列入下");Set<Student> keyset = ma.keySet();Iterator<Student> it = keyset.iterator();//Iterator <Student> it =keySet.iterator();while(it.hasNext()){Student key = it.next();String value = ma.get(key);sop("学生:"+key.getName()+"年龄:"+key.getAge()+"地址:"+value);}//用entry.Set取值sop("ENtry.set取值排列入下");Set<Map.Entry<Student , String >> entryset = ma.entrySet();Iterator<Map.Entry<Student , String >> it1 = entryset.iterator();//Iterator<Map.Entry<Student , String >> it = entrySet.iterator();while(it1.hasNext()){Map.Entry<Student , String > ma1 = it1.next();Student key = ma1.getKey();String value = ma1.getValue();sop("学生:"+key.getName()+"年龄:"+key.getAge()+"地址:"+value);}}}

(2)TreeMap练习2     //3

需求:asdasfsdasdasgdfhert”获取该字符串中的字母出现的次数,希望打印结果:a(1)c(2)

通过结果发现,每一个字母都有对应的次数。
说明字母和次数之间都有映射关系。
注意了,当发现有映射关系时,可以选择map集合。
因为map集合中存放就是映射关系。

为什么使用map集合呢?
当数据之间存在着映射关系时,就要先想map集合。


思路:
1.将字符串转换成字符数组。因为要对每一个字母进行操作
2.定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
3.遍历字符数组。
将每一个字母作为键去查map集合。
如果返回null,将该字母和1存入到map集合中。
如果返回不是null,说明该字母在map集合已经存在并有对应次数。
那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到map集合,覆盖调用原来键所对应的值。
4.将map集合中的数据变成指定的字符串形式返回。


import java.util.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){String s1 = charCount("asdasfsdasdasgdfhert");sop(s1);}public static String charCount(String str){char [] chs = str.toCharArray();//变成数组
<p><span style="white-space:pre"></span>//<span style="font-family:宋体;">泛型类接受的都是引用数据类型,所以要写基本的数据包装类</span><span style="font-family:Times New Roman;">(character,Interger),</span><span style="font-family:宋体;">而不是,</span><span style="font-family:Times New Roman;">char,int.</span></p>TreeMap<Character , Integer> trma =new  TreeMap<Character , Integer>();int count = 0;for(int i = 0 ;i<chs.length;i++) //length , length(),size{if(!((chs[i]>= 'a' && chs[i] <='z')||(chs[i]>='A' && chs[i] <='Z')))//避免算其他字符被拿进来continue;Integer  value = trma.get(chs[i]);sop("第i个-"+i+"--是--"+chs[i]+"--值--"+value);//这样也可以**************************************//if(value == null)//{//trma.put(chs[i],1);//}//else//{//value = value+1;////value++;//trma.put(chs[i],value);//}//这样也可以***************************************if(value != null){count = value;}else{count = 0;     //这个地方换了一个字符就一定要清零,否则结果不对}count++;sop("第i个-"+i+"--是--"+chs[i]+"出现次数"+count);trma.put(chs[i],count);}//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!StringBuilder sb = new StringBuilder();  //这个地方要好好看下,可以自定义打印的形式a(2)b(3)..Set<Map.Entry<Character , Integer>>  enset = trma.entrySet();Iterator<Map.Entry<Character , Integer>> it = enset.iterator();while(it.hasNext()){Map.Entry<Character , Integer> mapen = it.next();Character chs1 = mapen.getKey();Integer   in1 = mapen.getValue();sb.append(chs1+"("+in1+")");  }return sb.toString();}}

3.Map扩展知识   //2

有两种方法,没看出来有很大差别????????
一对多,一般都是把学生封装成对象,用后者方法
map集合被使用是因为具备映射关系。
winsun 下属业务部,工程部


业务部 下属 dx1  01
dx2  02
dx3  03


都按照年龄排序


工程部 下属 dx4  22
dx5  23
dx6  24

方法1,用map嵌套

import java.util.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){//这里可以写map.但是后面就不能写了,因为是接口,抽象的,不能实例化HashMap<String ,HashMap<String ,String > > winsun = new HashMap<String ,HashMap<String ,String > >();HashMap<String ,String > yewu = new HashMap<String ,String >();  //要放在前面,要不然后面无法添加HashMap<String ,String > gongcheng = new HashMap<String ,String >();winsun.put("yewubu",yewu);//这么写规不规范winsun.put("gongchengbu",gongcheng);yewu.put("dx1","22");yewu.put("dx2","25");yewu.put("dx3","26");gongcheng.put("dx4","27");gongcheng.put("dx5","25");gongcheng.put("dx6","24");sop("业务部人员信息");getPersonInfo(yewu);//获取业务部的人员信息   //如果想用toString怎么弄sop("工程部人员信息");getPersonInfo(gongcheng);//获取业务部的人员信息sop("获取部门信息");getDepartmentInfo(winsun);}public static void getDepartmentInfo(HashMap<String ,HashMap<String ,String > > tm){//用keySet取值sop("用的是keyset");Set<String> keyset = tm.keySet();Iterator<String> it = keyset.iterator();while(it.hasNext()){String key = it.next();HashMap<String ,String > value =tm.get(key);sop("key-"+key+"-value-"+value);}sop("用的是entryset");//用entrySetq取值Set<Map.Entry<String ,HashMap<String ,String >>> enset = tm.entrySet();//传的是TreeMap,这里用用Map.entry();Iterator<Map.Entry<String ,HashMap<String ,String >>> it1 = enset.iterator();while(it1.hasNext()){Map.Entry<String ,HashMap<String ,String >> map = it1.next();String key = map.getKey();HashMap<String ,String > value = map.getValue();sop("key-"+key+"-value-"+value);}}//public static void getPersonInfo(Map tm)//会报错,不兼容性的类型,object无法转换成Stringpublic static void getPersonInfo(HashMap<String , String> tm){//用keySet取值Set<String> keyset = tm.keySet();Iterator<String> it = keyset.iterator();while(it.hasNext()){String key = it.next();String value =tm.get(key);sop("key-"+key+"-value-"+value);}//用entrySetq取值Set<Map.Entry<String,String>> enset = tm.entrySet();//传的是TreeMap,这里用用Map.entry();Iterator<Map.Entry<String,String>> it1 = enset.iterator();while(it1.hasNext()){Map.Entry<String,String> map = it1.next()String key = map.getKey();String value = map.getValue();sop("key-"+key+"-value-"+value);}}}

方法2,把学生做成一个集合


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 String toString(){return age+":::"+name;}}class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){HashMap<String ,List<Person>> czbk = new HashMap<String ,List<Person>>();List<Person> yure = new ArrayList<Person>();List<Person> jiuye = new ArrayList<Person>();czbk.put("yureban",yure);czbk.put("jiuyeban",jiuye);yure.add(new Person("dx1",11));yure.add(new Person("dx2",13));jiuye.add(new Person("dx2",11));jiuye.add(new Person("dx11",11));Iterator<String> it = czbk.keySet().iterator();while(it.hasNext()){String roomName = it.next();List<Person> room =czbk.get(roomName);System.out.println(roomName);getInfos(room);}}public static void getInfos(List<Person> List){Iterator <Person> it = List.iterator();while(it.hasNext()){Person s = it.next();System.out.println(s);  //打印的其实就是toString}}}

四.集合框架的工具类

1.作为工具类,它里面的方法全是静态的不需要对象
2.不需要保证唯一,用list,但是要排序,又只能用tree
所以这里就是collections

注意:
public static <T extends Compareable <? super T>>void sort(List<T> list)
这句话的意思是T 必须是Compareable 的子类,<? super T>这个代表T的父类,可以传person

list集合中的元素想要排序都要进行比较,如果不写extend Comparable限定T,传过来如果是没有比较性,如果运行就会出错,然后comparable也要写泛型一般写Comparable<T>现在Comparable<? super T>? super T 表示用T或者用T的父类来比)

public static <T  extend Comparable<? super T>> void sort(List<T> list)



1.sort

import java.util.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){List<String> list = new ArrayList<String>();list.add("asdasd");list.add("qwe");list.add("sf");list.add("dfgdf");list.add("vsf");list.add("sdfr");list.add("yujghy");sop(list);//按存入的顺序打印sop("按自然顺序排序");Collections.sort(list); //collections不能给set用,因为他自己有treesetsop(list);//用二分法查找 //这里传入的元素是具有比较性的int index = Collections.binarySearch(list , "sdfr");//系统的//如果找不到就返回插入点sop("index--"+index);//用二分法查找  //传入不具备比较性的元素,用比较器自己写一下二分法查找!!!!自己写一下二分法查找!!!!sop("按自己写的自然顺序排序");Collections.sort(list, new NormalCompartor()); //注意这里的写法!!sop(list);sop("按字符长度排序");Collections.sort(list, new StrLengthCompartor());sop(list);//获取长度最长的String max = Collections.max(list);sop("max--"+max);}}class StrLengthCompartor implements Comparator<String>{public int compare(String s1 ,String s2){if(s1.length()>s2.length()){return -1;}elseif(s1.length()<s2.length()){return 1;}else{returns1.compareTo(s2);}}}class NormalCompartor implements Comparator<String>{public int compare(String s1 ,String s2){returns1.compareTo(s2);}}

2.替换部分元素

import java.util.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){//replacePartDemo();replaceAllDemo();}public static void replacePartDemo(){List<String> list = new ArrayList<String>();list.add("abcd");list.add("aaa");list.add("qwe");list.add("z");list.add("qweqwe");list.add("sd");sop(list);

(1)使用替换函数replaceAll

sop("使用替换函数");//static <T> boolean replaceAll(List<T>,T oldVal , T newVal)boolean flag = Collections.replaceAll(list,"z","ww");sop(flag);sop(list);}

(2)替换所有元素

public static void replaceAllDemo(){List<String> list = new ArrayList<String>();list.add("fgj");list.add("fghr");list.add("se");list.add("z");list.add("czxc");list.add("bcv");sop(list);

(3)使用替换函数fill

sop("使用替换函数fill");//static <T> boolean replaceAll(List<T>,T oldVal , T newVal)Collections.fill(list,"ww");sop(list);}}

3.实现反转

import java.util.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){orderDemo();}public static void orderDemo(){//TreeSet<String>  ts = new TreeSet<String>(new StrComparator());//使用自定义比较器 //reverseOrder()返回一个比较器,它强行逆转实现了Comparable接口的对象Collection的自然顺序//TreeSet<String>  ts = new TreeSet<String>(Collections.reverseOrder());//最简单的方法//系统自带,collections.reverseorder()返回的是一个比较器//  reverseOrder()返回一个比较器,它强行逆转指定比较器的顺序//TreeSet<String>  ts = new TreeSet<String>(Collections.reverseOrder(new  StrComparator())); //强制反转已有的比较器,这个方法更牛//TreeSet<String>  ts = new TreeSet<String>();//使用默认的比较方式ts.add("abcde");ts.add("aaa");ts.add("kkk");ts.add("ccc");Iterator it = ts.iterator();while(it.hasNext()){sop(it.next());}}}class StrComparator implements Comparator<String>    //自定义的比较器{public int compare(String s1, String s2)  //在这里加了个分号,报错误,缺少方法主体,或声明抽象{return  s2.compareTo(s1);//正常的情况是s1.compareTo(s2),但是这里我们需要倒序}}


五..Arrays:用于操作数组的工具类。

1.asList:将数组变成list集合

还有String变成char???????????
import java.util.*;class CollectionDemoText{public static void sop(Object obj){System.out.println(obj);}public static void main(String[] args){int[] arr = {2,4,5};sop(arr);//只会打印哈希值sop(Arrays.toString(arr)); //返回字符串形式[2,4,5]//把数组变成list集合有什么好处?//可以使用集合的思想和方法来操作数组中的元素。//注意:将数组变成集合,不可以使用集合的增删方法。//因为数组的长度是固定。//contains//get//indexof()//subList();//如果你增删。那么回反生unsupportedOperationException,//sop(list);String[] arr = {"asd","qwe","sdf"} ;List<String> list = Arrays.asList(arr)}}

六.一些扩展


1.集合变数组

Collection接口中的toArray方法。。传什么类型,返回就什么类型


import java.util.*;class collectionToArray{public static void main(String[] args){ArrayList<String> a1 = new ArrayList<String>(); a1.add(“abc1”);a1.add(“abc2”);a1.add(“abc3”);

1.指定类型的数组到底要定义多长呢?

当指定类型的数组长度小于集合的size,那么该方法内部会创建一个新的数组,长度为集合的size.

当指定类型的数组长度大于了集合的size,就不会新创建了数组,而是使用传递进来的数组。所以创建一个刚刚好的数组最优。(把 new String[0]改为new String[a1.size()]

 

2,为什么要将集合变数组?

为了限定对元素的操作,不需要进行增删了(集合长度可变,数组长度固定)

 

String[] arr = a1.toArray(new String[0](改成String[a1.size()]))//如果Sting[5](超过数组长度),会打印出[abc1,abc2,abc3,null,null]System.out.println(Arrays.toString(arr)); //[abc1,abc2,abc3] } }

2.高级for循环


格式:

for(数据类型  变量名  : 被遍历的集合(Collection)或者数组)

{

 

}

注意:

对集合进行遍历。

只能获取集合元素。但是不能对集合进行操作

迭代器除了遍历,还可以进行remove集合中元素的动作。

如果是用ListIterator,还可以在遍历过程中对集合进行增删改查的动作。

 

传统for和高级for有什么区别呢?

高级for有一个局限性。必须有被遍历的目标。

 

建议在遍历数组的时候,还是希望用传统的for.因为传统for可以定义脚标


import java.util.*;class ForEachDemo{public static void main(String[] args){ArrayList<String> a1 =new ArrayList<String>(); a1.add(“abc1”);a1.add(“abc2”);a1.add(“abc3”); for(String s : a1)   //只能取出,不能改变连remove都不行(iterator可以){//s= “KK”;//不会影响打印的结果System.out.println(s);} System.out.println(a1);/*Iterator <String> it = a1.iterator();while(it.hasNext()){System.out.println(it.next());}*/复杂了 */  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));//  打印 1::a  2::b  3::c}  /*Set<Map.Entry<Interger , String>> entrySet = hm.entrySet();for(Map.Entry<Integer, String > me : entrySet)*///复杂了可以简写成下面的for(Map.Entry<Integer , String >   me : hm.entrySet()){System.out.println(me.getKey()+”------”+me.getValue());}

3.方法的可变参数

在使用时注意:可变参数一定要定义在参数列表最后面。

例如

如果

show (“haha”,2,3,4,5,6);

则需要show函数这么写

public static void showString str , int ...arr 

class  ParamethodDemo{public static void main(String[] args){/*可变参数其实就是上一种数组参数的简写形式。不用每一次都手动的建立数组对象。只要将要操作的元素作为参数传递即可。隐式将这些参数封装成了数组。 */show(2);show(2,3,4,5,6);//打印 5 } public static void show(int...arr)(三个点){ //System.out.println(arr);//打印[I@de6ced](数组的哈希值)System.out.println(arr.length);//打印 1  //这里用length?????不是应该用size吗}  }

4.静态导入

/*

StaticImport 静态导入。

*/

import  java.util.*;

import  static java.util.Arrays.*;//导入的是Arrays这个类中的所有静态成员。

import  static java.lang.System.*;//导入了system类中所有静态成员。

(输出与不用写System.out,可以直接写out.

当类名重名时,需要指定具体包名。

当方法重名时,指定具备所属的对象或者类。

 

class staticImport  extends Object

{

public static void main(String[]  args)

{

int[]  arr = {3,1,5};

sort(arr);

int index = binarySearch(arr ,1);  //排完序才能查找,因为用的是二分法

 

System.out.println(Arrays.toString(arr));//因为extends Object中也有tostring方法,但是不能传参数,先进入object,如果去掉Arrays会报错

当类名重名时,需要指定具体包名。

当方法重名时,指定具备所属的对象或者类。

 

 

 

System.out.println(“Index=”+index);

 

}

 

/*

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);

 

}

*/

 

}





0 0
原创粉丝点击