黑马程序员——集合
来源:互联网 发布:超人软件下载站 编辑:程序博客网 时间:2024/05/16 05:05
------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
Day14
01-集合框架(体系概述) java.util包Collection接口
1 为什么出现集合类?
因为面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的操作,就对对象进行存储。集合就是存储对象最常用的一种方式
2 数组和集合类同是容器,有何不同?
数组虽然也可以存储对象,但是长度是固定的,集合长度可变
数组中可以存储基本数据类型,就和只能存储对象
3 集合类的特点
集合只用于存储对象,集合长度是可变的,集合可以存储不同类型的对象
4 为什么会出现这么多的容器?
因为每一个容器对数据的存储方式都有不同。这个存储方式称为:数据结构
02-集合框架(共性方法)
1 add()方法的参数类型是Object,以便于接受任意类型的对象
2 集合中存储的都是对象的引用(地址)
ArrayLista1 = new ArrayList(); //创建一个集合容器。使用Collection接口的子类ArrayList
// 1 添加元素
a1.add("java01");
// 1 打印集合a1,结果为[java01, java02, java03, java04]
sop(a1);
//3 删除元素
a1.remove("java02");
a1.clear(); //清空元素
//4 判断元素
sop("java03是否存在:"+a1.contains("java03"));
sop("集合是否为空:"+a1.isEmpty());
//取交集,a1只会保留和a2中相同的元素
a1.retainAll(a2);
//移除a1中与a2相同的元素
a1.removeAll(a2);
}
03-集合框架(迭代器)
什么是迭代器?其实就是集合取出元素的方式
Iterator it =a1.iterator(); //获取集合的迭代器,用于取出集合中的元素
while(it.hasNext()) //如果仍有元素可以迭代,则返回 true。
{
sop(it.next()); //返回迭代的下一个元素。
}
还可写成:
for(Iteratoritr = a1.iterator(); it.hasNext(); )
{
sop(itr.next());
}
理解:每一个容器的数据结构不同,取出元素的动作不同,但是都有共性内容(取出和判断),那么可以将共性抽取,定义在集合内部(内部类);这样他就可以直接访问集合内容的元素。这些内部类都符合一个规则Iterator 接口。通过调用对外的方法iterator()方法就可获得其子类对象
----------------------------------------------------List集合---------------------------------------
04-集合框架(List集合共性方法)
Collection
|—List 元素是有序的,元素可重复。因为该集合体系中有索引
|—Set 元素是无序的,元素不可重复
增:add(index, element); addAll(index,Collection)
删:remove(index)
改:set(index, element)\
查:get(index) indexOf(element) subList(from, to) listIterator();
int index =a1.indexOf("java02");//获取对象的位置
Listsub = a1.subList(1, 3); //返回列表中 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
a1.add(1,"java06"); //在1角标处插入元素
a1.remove(2); //删除指定位置元素的引用
a1.set(2,"java004"); //修改指定位置元素为java004
a1.get(1); //通过角标获取元素
List还可以通过角标遍历取元素,也可以用迭代器
05-集合框架(ListIterator)列表迭代器
List集合特有的迭代器,ListIterator是Iterator的子接口,继承了Iterator添加自己的方法。Iterator接口中只有hasNext() next() remove()三个方法
在迭代时,不可以通过集合对象的方法(add)操作集合中元素,因为会发生ConcurrenModificationException(并发修改)异常,所以在迭代是,只能通过迭代器操作元素。可是Iterator的方法是有限的,只能对元素进行判断,取出,删除的操作;如果想要其他操作如添加,修改等,就需要使用其子接口ListIterator。该接口只能通过List集合的listIterator方法获取
boolean hasNext() 正向迭代,如果有下一个元素返回true
boolean HasPrevious();逆向迭代列表,列表迭代器前面有元素返回true
ListIterator li =arr.listIterator();
sop(li.hasPrevious()); //返回false,因为li现在指向第一个元素,他前面没元素
while(li.hasNext())
{
Objectobj = li.next();
if(obj.equals("java02"))
//li.add("java009"); 在迭代过程中添加元素
li.set("java06"); //修改元素
}
while(li.hasNext())
{
sop(li.hasPrevious()); //返回true,因为li现在指向最后一个元素
}
sop(arr);
06-集合框架(List集合具体对象的特点)
Collection
|---List:元素是有序的,可重复,因为该集合体系有索引
|—ArrayList:底层的数据结构使用的是数组数据结构。
特点:查询速度快,增删稍慢,线程不同步
|—LinkedList:底层使用的链表数据结构。特点:增删速度快,查询慢
|—Vector:底层是数组数据结构。线程同步,被ArrayList代替了
07-集合框架(Vector中的枚举)
枚举就是Vector特有的取出方式。其实和迭代器是一样的。
因为枚举的名称以及方法名称都过长,所以被迭代器取代了
Vector v = new Vector();
v.add("java01");
v.add("java02");
v.add("java03");
Enumerationen = v.elements(); //返回此向量数组的枚举
while(en.hasMoreElements()) //测试此枚举是否包含更多的元素
{
System.out.println(en.nextElement());//如果此枚举对象至少还有一个可提供的元素,则返回此枚举的下一个元素
}
08-集合框架(LinkedList)
LinkedList:特有方法:
addFirst(); addLast();
getFirst() getLast()
获取元素,但不删除元素,如果集合中没有元素,会出现NoSuchElementException
removeFirst() removeLast()
获取元素,但是会被删除,如果集合中没有元素,会出现NoSuchElementException
在JDK1.6出现了代替方法:
offerFirst() offerLast() 在列表开头/ 结尾插入指定元素
peekFirst() peekLast()
获取但不移除才列表第一个或最后一个元素,如果列表为空,返回null
pollFirst() pollLast()
获取并移除列表第一个或最后一个元素,列表为空时返回null
09-集合框架(LinkedList练习)
/*
* 使用LinkedList模拟一个堆栈和队列数据结构
* 堆栈:先进后出 如同一个杯子
* 队列:先进先出 First in First out FIFO如同一个水管
*/
// 堆栈:加入第一个,取出第一个,先加入后被取走
class DuiZhan
{
private LinkedList link;
DuiZhan()
{
link = new LinkedList();
}
public void myAdd(Object obj)
{
link.addFirst(obj); //将元素添加到第一个
}
public Object myGet()
{
return link.removeFirst(); //取出第一个元素
}
public boolean isNull()
{
return link.isEmpty();
}
}
//队列:加入第一个,取最后一个,先加入先被取走
class DuiLie
{
private LinkedList link;
DuiLie()
{
link = new LinkedList();
}
public void myAdd(Object obj)
{
link.addFirst(obj); //将元素添加到第一个
}
public Object myGet()
{
return link.removeLast(); //取出最后一个元素
}
public boolean isNull()
{
return link.isEmpty();
}
}
堆栈:把removelast()改为removeFirst()
10-集合框架(ArrayList练习)
在迭代中循环调用next一次,就要hasNext判断一次,否则会出异常
//去除ArrayList集合中的重复元素
public static ArrayListsingleElement(ArrayList a1)
{
ArrayListnewAL = new ArrayList();
Iterator it = a1.iterator(); //获取a1的迭代器
while(it.hasNext())
{
Objectobj = it.next(); //接受a1中的元素
if(!newAL.contains(obj)) //当newAL中不存在obj时才加进去
newAL.add(obj);
}
return newAL;
}
11-集合框架(ArrayList练习2)
List集合判断元素是否相同,依据的是元素的equals方法。比如contains和remove
public static ArrayListsingleElement(ArrayLista1)
{
ArrayList newAL = new ArrayList();
Iterator it = a1.iterator(); //获取a1的迭代器
while(it.hasNext())
{
Objectobj = it.next(); //接受a1中的元素
if(!newAL.contains(obj)) //contain方法在底层是调用equals方法,所以重写equals
newAL.add(obj);
}
return newAL;
}
重写equals();
public boolean equals(Objectobj) //重写,让它比较的是内容而不是地址
{
if(!(obj instanceof Person))
return false;
Personp = (Person)obj;
System.out.println(this.name +"^^^^^^"+p.name);
return this.name.equals(p.name) && this.age ==p.age; //此处equals是String中的,比较内容
}
----------------------------------Set集合----------------------------------------------------
12-集合框架(HashSet)
\list有角标,set无角标,无序不重复。Set集合的功能和Collection是一致的
|—Set:元素无序(存入和取出的顺序不一定一致),元素不可重复
|—HashSet:底层数据结构是哈希表,按哈希表排序。线程不同步。
保证元素唯一性原理:判断元素hashCode值(找到其存储区域),如果不存在存储区域说明不存在。当找到存储区域时,判断equals方法,是否为true;如果false就存。所以一般复写这两个方法
注意:对于判断元素是否存在,删除等操作,依赖的方法是元素的hashCode和equals方法
|—TreeSet:可以对Set集合中的元素进行排序。底层数据结构是二叉树
保证元素唯一性依据:compareTo方法return0
排序方式两种(让元素自身具有可比性;让集合自身具备比较性)
HashSeths = new HashSet();
System.out.println(hs.add("java01")); //true
System.out.println(hs.add("java01")); //false 因为已存在,元素不重复
hs.add("java02");
hs.add("java03");
Iteratorit = hs.iterator(); //获取集合迭代器
while(it.hasNext())
{
System.out.println(it.next()); //打印结果无序
}
13-集合框架(HashSet存储自定义对象)
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("a1",11)); //先判断hashCode值,相同时再用equals比较,这两个方法在ArrayListTest2中重写了
//hs.contains(newPerson("a2",12));
//hs.remove(newPerson("a4",14)); //判断元素是否存在和删除操作都会先调用hashCode方法,相同时在调用equals
Iteratorit = hs.iterator();
while(it.hasNext())
{
Personp = (Person)it.next();
System.out.println(p.getName()+"::::"+p.getAge());
}
}
14-集合框架(HashSet判断和删除的依据)
判断元素是否存在和删除操作都会先调用hashCode方法,相同时在调用equals。依赖于hashCode和equals方法
Day15
01- 集合框架(TreeSet)按字母顺序排序,大写排前面
|—TreeSet:可以对Set集合中的元素进行排序。底层数据结构是二叉树
保证元素唯一性依据:compareTo方法return0
排序方式两种(让元素自身具有可比性;让集合自身具备比较性)
TreeSet第一种排序方式:让元素自身具备比较性。元素需要实现Comparable接口,覆盖compareTo();这种方式称为元素的自然排序,或者默认排序
第二种方式:当元素自身不具备比较性时,或者比较性不是所需要的。这时就需要让集合自身具备比较性。
定义比较器,并将比较器对象作为参数传给TreeSet构造函数,在集合一初始化时就具有比较性
定义一个类,实现Comparator接口,覆盖compare()方法
当两种排序都存在时,以比较器为主
02-集合框架(TreeSet存储自定义对象)
第一种排序方式
往TreeSet里面存对象要有可比性。排序,这时这个自定义类要实现Comparable接口
此接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo 方法被称为它的自然比较方法
int compareTo(T o)
比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数。
importjava.util.Iterator;
import java.util.TreeSet;
/*
* 需求:往TreeSet集合中存储自定义学生对象,想按照学生年龄进行排序
* 当年龄相同时,将姓名按字典顺序排序
*/
class Student implements Comparable //改接口强制让学生具备比较性
{
private String name;
private int age;
Student(Stringname,int age)
{
this.name = name ;
this.age = age;
}
public int compareTo(Objectobj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象");
Students = (Student)obj;
System.out.println(this.name+"……compareto……"+s.name);
if(this.age>s.age)
return 1;
if(this.age==s.age) //当主要条件相同,判断次要条件
{
return this.name.compareTo(s.name); //String类实现了Comparabe接口,重写compareTo按字典顺序排序
}
return -1;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
public class TreeSetDemo
{
public static void main(String[]args)
{
TreeSetts = new TreeSet();
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi06",19));
ts.add(new Student("lisi06",19)); //重复元素进不来
Iteratorit = ts.iterator();
while(it.hasNext())
{
Studentstu = (Student)it.next();
System.out.println(stu.getName()+"……"+stu.getAge());
}
}
}
03-集合框架(二叉树)
04-集合框架(实现Comparator方式排序)
TreeSet第二种排序方式:让集合自身具比较性
* 定义一个类,实现Comparator接口,覆盖compare()方法
* 当两种排序都存在时,以比较器为主
class MyCompare implements Comparator //定义比较器类
{
public int compare(Objecto1,Object o2)
{
Students1 = (Student)o1;
Students2 = (Student)o2;
int num =s1.getName().compareTo(s2.getName()); //按姓名排序
if(num == 0) //姓名相同时,按年龄排
{
return newInteger(s1.getAge()).compareTo(newInteger(s2.getAge())); //Integer类实现了Comparable重写了compareTo()
/*
* if(s1.getAge()>s2.getAge())也可这样写
* return1;
* if(s1.getAge()==s2.getAge())
* return0;
* return -1;
*/
}
return num; //按姓名排,当姓名不同时。
}
}
public class TreeSetDemo2
{
public static void main(String[]args)
{
TreeSetts = new TreeSet(new MyCompare()); //让集合对象自身具比较性,传入参数为比较器
ts.add(new Student("lisi02",22));
ts.add(new Student("lisi007",20));
ts.add(new Student("lisi09",19));
ts.add(new Student("lisi06",19));
ts.add(new Student("lisi06",19)); //重复元素进不来
Iteratorit = ts.iterator();
while(it.hasNext())
{
Studentstu = (Student)it.next();
System.out.println(stu.getName()+"……"+stu.getAge());
}
}
}
05-集合框架(TreeSet练习) (1)
/*
* 练习:按字符串长度排序
* 字符串本身具备比较性。但是它的比较方式不是所需要的,这时就只能使用比较器
*/
public class TreeSetTest
{
public static void main(String[]args)
{
TreeSetts = new TreeSet(newStrLenComparator());
ts.add("abds");
ts.add("aaa");
ts.add("csd");
ts.add("a");
ts.add("ef");
Iteratorit = ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
class StrLenComparator implements Comparator
{
public int compare(Objecto1,Object o2)
{
Strings1 = (String)o1;
Strings2 = (String)o2;
int num = newInteger(s1.length()).compareTo(s2.length());
if(num==0) //当主要因素相同时,还要考虑次要因素排序
return s1.compareTo(s2);
return num;
}
}
05-集合框架(TreeSet练习) (2)
/*
* 集合框架中的泛型
*/
public class GenericDemo
{
public static void main(String[]args)
{
TreeSet<String>ts = new TreeSet<String>(new LenComparator());
ts.add("abds");
ts.add("aaa");
ts.add("csd");
ts.add("a");
ts.add("ef");
Iteratorit = ts.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
}
}
//比较器,让字符串倒序
class LenComparator implements Comparator<String>
{
public int compare(Stringo1,String o2)
{
int num = newInteger(o2.length()).compareTo(o1.length());
if(num==0) //当主要因素相同时,还要考虑次要因素排序
return o2.compareTo(o1);
return num;
}
}
06-集合框架(泛型概述)、
泛型:JDK1.5版本以后出现新特性。用于解决安全问题,是一个类型安全机制
好处:1 将运行时期出现问题ClassCastException(聚合存放对象肯定是要操作对象的,将对象取出操作要用到对象所特有方法,这时就要转型),转移到了编译时期,方便于程序员解决问题,让运行时问题减少。
2 避免了强制转换麻烦
泛型格式:通过<>来定义要操作的引用数据类型;;;通常在集合框架中很常见
08-集合框架(泛型类)
泛型类:当类中要操作的引用数据类型不确定时,早起定义Object来完成扩展;现在定义泛型来完成扩展。。泛型类一确定(创建对象),要操作的类型就确定了
class Student{}
class Worker{}
//泛型前做法
class Tool
{
private Object obj;
public void setObject(Objectobj)
{
this.obj = obj;
}
public Object getObject()
{
return obj;
}
}
//泛型:将运行时的异常转换到编译时期
class Utils<QQ>
{
private QQ q;
public void setObject(QQ q)
{
this.q = q;
}
public QQ getObject()
{
return q;
}
}
public class GenericDemo3
{
public static void main(String[]args)
{
Toolt = new Tool();
t.setObject(new Student()); //传入一个Student对象
Workerw = (Worker)t.getObject(); //将Student对象转换为Workwe对象出错
}
}
09-集合框架(泛型方法)(静态泛型方法)
/*
* 泛型类定义的泛型,在整个类中有效。如果被方法使用,
* 那么泛型类对象明确要操作的具体类型后,所有要操作的类型就已经固定了
* 为了让不同方法可以操作不同类型,而且类型还不确定,就可以将泛型定义在方法上
*
* 特殊之处:静态方法不可以访问类上定义的泛型。静态先加载,那时候还没有泛型类的对象,所以不能访问T
* 如果静态方法操作的引用数据类型不确定,可将泛型定义在方法上
*/
class Demo<T> //泛型类
{
public <T> void show(T t)
{
System.out.println("show "+t);
}
public <Q> void print(Q q) //泛型方法
{
System.out.println("show "+q);
}
public static <W> void method(W w) //静态泛型方法
{
System.out.println("method "+w);
}
}
public class GenericDemo4
{
public static void main(String[]args)
{
Demod = new Demo();
d.show("haha");
d.show(new Integer(4));
d.print("heihie");
}
}
11-集合框架(泛型接口)
//泛型定义在接口上 注意:用到泛型的时候必须传参数
interface Inter<T>
{
void show(T t);
}
class InterImpl implementsInter<String> //子类实现的时候指定了类型,只能操作String
{
public void show(String t)
{
System.out.println("show::"+t);
}
}
classInterImpl2<T> implements Inter<T> //实现时不指定,但是要传参数<T>,又用户自己指定
{
public void show(T t)
{
System.out.println("show::"+t);
}
}
12-集合框架(泛型限定)
<?> 通配符,也可以理解为占位符,告诉别人这里有泛型
? extends E:可以接受E类型或者E类型的子类型。 上限
? super E : 可以接受E类型或者E的父类型。 下限
泛型限定是用来对泛型的扩展
class Comp implements Comparator<Persons> //定义比较器时传入Person作为反泛型参数
{
public int compare(Persons p1,Persons p2)
{
returnp2.getName().compareTo(p1.getName());
}
}
TreeSet<Workers> ts1 = new TreeSet<Workers>(new Comp()); //传入的比较器可以比较所有Persons的子类
ts1.add(new Workers("sadq02"));
ts1.add(new Workers("sadq03"));
Day16
01-集合(Map概述)
Map集合:该集合存储键值对,一对一对往里存。而且要保证键的唯一性
1、添加
put(K key, V value) 返回的是对应键的值,如果没有,返回空
putAll(Map<?extends K,? extends V> m)
2、删除
clear()
remove(Objectkey)
3、判断
containsKey(Objectkey)
containsValue(Objectvalue)
isEmpty()
4、获取
get(Objectkey) 返回指定键所映射的值;若映射不包含该键的映射关系,则返回 null。
size() 返回此映射中的键-值映射关系数。
values() 返回此映射中包含的值的 Collection 视图
entrySet() 返回此映射中包含的映射关系的 Set 视图。
keySet() 返回此映射中包含的键的 Set 视图。
02-集合(Map子类对象特点)
Map
|—Hashtable 底层是哈希表数据结构,不可存入null键null值。该集合是线程同步的。Jdk1.0 效率低
|—HashMap 底层是哈希表数据结构,允许使用null键null值。该集合是不同步的。Jdk1.2 效率高
|—treeMap 底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序
和Set很像,其实Set底层就是使用了Map集合
03-集合(Map共性方法) MapDemo
Map<String,String> map = newHashMap<String,String>();
//添加元素,如果出现添加时相同的键,后添加的值会覆盖原有的键对应的值,并put方法会返回被覆盖的值
System.out.println("put:"+map.put("01", "zhangsan1")); //put:null
System.out.println("put:"+map.put("01", "wangwu")); //put:zhangsan1 返回01对应的值,并替换掉
map.put("02","zhangsan2");
map.put("03","zhangsan3");
System.out.println("containsKey:"+map.containsKey("022")); //containsKey:false
System.out.println("remove:"+map.remove("02")); //remove:zhangsan2
System.out.println("get:"+map.get("023")); //get:null
map.put("04",null);
//可以通过get方法返回值来判断一个键是否存在。通过返回nill来判断
System.out.println("get:"+map.get("04")); //get:null
Collection<String>coll = map.values(); //获取集合中所有的值,因为Map构造时V=String
System.out.println(coll); //[null, wangwu,zhangsan3]
System.out.println(map); //{04=null, 01=wangwu,03=zhangsan3}
04-集合(Map-keySet) KeySetDemo
Set<K> keySet() 返回此映射中包含的键的 Set 视图。
将map中所有的键存入Set集合。因为Set具备迭代器。所以可以迭代方式取出所有的键,再根据get方法,获取每个键对应的值
public static void main(String[]args)
{
Map<String,String>map = new HashMap<String,String>();
map.put("02","zhangsan2");
map.put("03","zhangsan3");
map.put("01","zhangsan1");
map.put("04","zhangsan4");
Set<String>keySet = map.keySet(); //先获取,map集合的所有键的Set集合,keySet()
Iterator<String>it = keySet.iterator(); //有了Set集合,就可以获取其迭代器
while(it.hasNext())
{
Stringkey = it.next(); //迭代器取出所有键
Stringvalue = map.get(key); //get()方法取出键对应的值
System.out.println("key:"+key+",value:"+value);
}
}
05-集合(Map-entrySet) EntrySetDemo
Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射关系的 Set 视图
将map集合中的映射关系存入到Set集合中,这个关系的数据类型是Map.Entry
Map<String,String> map = newHashMap<String,String>();
map.put("02","zhangsan2");
map.put("03","zhangsan3");
map.put("01","zhangsan1");
map.put("04","zhangsan4");
//将Map集合中的映射关系取出,存入到Set集合中
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();//这个映射关系的数据类型是Map.Entry
Stringkey = me.getKey(); //通过Map.Entry中的getKey()和getValue()获取键和值
Stringvalue = me.getValue();
System.out.println("key:"+key+" ,value:"+value);
}
其实Map.Entry是Map接口的类部接口。(如下)
interface Map
{
public static interface Entry
{
public abstract Object getKey();
public abstract Object getValue();
}
}
06-集合(Map练习) java文件MapTest
import java.util.*;
/*
* 每一个学生都有对应归属地。学生属性:姓名,年龄
* 注意:姓名和年龄相同的视为同一个学生,保证学生唯一性
*/
//描述学生
class Student implementsComparable<Student>
{
private String name;
private int age;
Student(Stringname,int age)
{
this.name = name;
this.age = age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public int compareTo(Students) //重写Comparable接口的方法,让学生具备比较性
{
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() //重写hashCode方法
{
return name.hashCode()+age*34;
}
public boolean equals(Object obj)//重写equals方法
{
if(!(obj instanceof Student))
throw newClassCastException("类型不匹配");
Students = (Student)obj;
return this.name.equals(s.name) && this.age == s.age;
}
public String toString()
{
return name+":"+age;
}
}
public class MapTest
{
public static void main(String[]args)
{
//定义map容器,将学生作为键,地址为值,存入
HashMap<Student,String>hm = new HashMap<Student,String>();
hm.put(new Student("lisi1",21),"beijing");
hm.put(new Student("lisi1",21),"shanghai");
hm.put(new Student("lisi3",23),"nanjing");
hm.put(new Student("lisi4",24),"hunan");
//第一种取出方式keySet
Set<Student>keySet = hm.keySet(); //获取所有键值,也就是学生
Iterator<Student>it = keySet.iterator();
while(it.hasNext())
{
Studentstu = it.next();
Stringaddr = hm.get(stu);
System.out.println(stu+":"+addr);
}
//第二种取出方式
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();
Studentst = me.getKey();
Stringaddr = me.getValue();
System.out.println(st+"…………"+addr);
}
}
}
07-集合(TreeMap练习) java文件TreeMapDemo
定义的比较器类用来让TreeMap具比较性,唯一性
import java.util.*;
/*
* 因为数据是以键值对形式存在的,所以要使用可以排序的Map集合。TreeMap
*/
class StuNameComparator implementsComparator<Student> //比较器类
{
public int compare(Students1,Student s2)
{
int num =s1.getName().compareTo(s2.getName());
if(num == 0)
return newInteger(s1.getAge()).compareTo(newInteger(s2.getAge()));
return num;
}
}
public class TreeMapDemo
{
public static void main(String[]args)
{
//定义Treemap容器,将学生作为键,地址为值,存入.此容器在保证元素唯一性和排序时只调用compareTo
TreeMap<Student,String>tm = new TreeMap<Student,String>(newStuNameComparator());
tm.put(new Student("lisi1",23),"beijing");
tm.put(new Student("lisi2",25),"shanghai");
tm.put(new Student("lisi3",21),"nanjing");
tm.put(new Student("lisi4",28),"hunan");
//第一种取出方式keySet
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();
Studentstu = me.getKey();
Stringaddr = me.getValue();
System.out.println(stu+":"+addr);
}
}
}
08-集合(TreeMap练习-字母出现的次数) TreeMapDemo2
“sadwerfecdsaasadf”获取该字符串中的个字母出现的次数。打印结果:a(4)c(1)…… 因为Character实现了Comparable接口,具比较性(排序)
通过结果发现,每个字母都有对应的次数,说明字母和次数之间有映射关系。当发生有映射关系是,可以选择map集合,因为map集合中存放的就是映射关系
public static StringcharCount(String str)
{
int count = 0;
char[] chs =str.toCharArray();
TreeMap<Character,Integer>tm = new TreeMap<Character,Integer>(); //创建TreeMap对象
for(int x = 0;x<chs.length;x++)
{
if(!(chs[x]>='a' &&chs[x]<='z' || chs[x]>= 'A' && chs[x]<='Z'))
continue; //当不是字母时,结束本次循环,继续下次循环
Integervalue = tm.get(chs[x]);
if(value != null)
count= value;
count++;
tm.put(chs[x],count);
count= 0; //每次循环后归0
}
StringBuildersb = new StringBuilder(); //定义字符串缓冲区,存放字母和数字
Set<Map.Entry<Character,Integer>> entrySet = tm.entrySet(); //获取Map集合中所有映射关系
Iterator<Map.Entry<Character,Integer>> it =entrySet.iterator(); //获取set集合迭代器
while(it.hasNext())
{
Map.Entry<Character,Integer> me = it.next();
Characterch = me.getKey();
Integervalue = me.getValue();
sb.append(ch+"("+value+")");
}
return sb.toString();
}
09-集合(Map扩展) MapDemo1
Map集合被使用是因为具备映射关系
* 1 Map集合中嵌套Map集合 map学校(班级,map学生(学号,姓名))
* 2 通常将学生封装为对象
day17(集合框架的工具类) java.util包
10-集合(Collections-sort) CollectionsDemo
List集合本来不可以排序,怎样村就怎样出。但是用集合工具类可以给List集合排序
1 static <T extends Comparable<? super T>> void sort(List<T> list) 根据元素的自然顺序 对指定列表按升序进行排序。这适合元素T自身具备比较性,比如String
//sort()方法中的参数集合T必须要有比较性,不然运行时挂了,因为将T转换为comparable时异常,
//所以继承Comparable,Comparable使用泛型,T的父类即可
Collections.sort(lt); // String类本身复写了compareTo();
System.out.println(lt); //[abcd, few, ghjmk, z,z]
2 static <T> void sort(List<T> list, Comparator<? super T> c) 根据指定比较器产生的顺序对指定列表进行排序。当元素自身不具备比较性或者不是想要的,可以传递一个比较器对List集合元素排序
//定以比较器,首先根据字符串长度排序,长度相同时自然排序
class StrLenComparator implementsComparator<String>
{
public int compare(String s1,String s2) {
if(s1.length()>s2.length())
return 1;
if(s1.length()<s2.length())
return -1;
returns1.compareTo(s2); //长度相同时自然排序
}
}
Collections.sort(lt ,newStrLenComparator()); //传入比较器
System.out.println(lt); //[z, z, few, abcd, ghjmk]
day17-11-集合(Collections-max) CollectionsDemo
static <T> T max(Collection<? extends T> coll,Comparator<? super T> comp)
根据指定比较器产生的顺序,返回给定 collection 的最大元素。
day17-12-集合(Collections-binarySearch) CollectionsDemo
static <T> int binarySearch(List<? extends Comparable<? super T>> list,T key)
使用二分搜索法搜索指定列表,以获得指定对象。
如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。插入点被定义为将键插入列表的那一点:即第一个大于此键的元素索引;如果列表中的所有元素都小于指定的键,则为 list.size()。注意,这保证了当且仅当此键被找到时,返回的值将 >= 0。
day17-13-集合(Collections-替换反转) CollectionsDemo1
static <T> void fill(List<? super T> list, T obj) 使用指定元素替换指定列表中的所有元素
static <T> boolean replaceAll(List<T> list, T oldVal, T newVal)
使用另一个值替换列表中出现的所有某一指定值。
static void reverse(List<?> list) 反转指定列表中元素的顺序。
static void swap(List<?>list, int i, int j) 在指定列表的指定位置处交换元素。
其实reverse底层就是调用了swap方法
static voidshuffle(List<?> list, Random rnd) 使用指定的随机源对指定列表进行置换。(洗牌)
day17-14-集合(Collections-reverseOrder) 逆转排序
static <T>Comparator<T> reverseOrder()
返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
static <T>Comparator<T> reverseOrder(Comparator<T>cmp)
返回一个比较器,它强行逆转指定比较器的顺序。
例子:TreeSet<String> ts=
new TreeSet<String>(Collections.reverseOrder(new StrLenComparator()));
将一个比较器逆转
day17-15-集合(Collections-SynList)返回同步集合
原理:其实在底层,这些方法内部是通过 new synchronizedList(List)对象。将需要同步的集合传入。通过synchronizedList类的构造方法返回一个同步的集合。这个类中重写了集合的所有方法,都加了同步并使用同一个锁。
static <T>List<T> synchronizedList(List<T>list) 返回指定列表支持的同步(线程安全的)列表。
static <K,V>Map<K,V> synchronizedMap(Map<K,V>m) 返回由指定映射支持的同步(线程安全的)映射。
static <T>Set<T> synchronizedSet(Set<T>s) 返回指定 set 支持的同步(线程安全的)set。
day17-16-集合(Arrays) ArraysDemo java,util包
Arrays:用于操作数组的工具类,里面都是静态方法。而且都是重载
static <T> List<T> asList(T... a) 返回一个受指定数组支持的固定大小的列表。(数组转换为集合)
binarySearch() 使用二分搜索法来搜索指定数组
copyOf() 复制指定的数组
copyOfRange() 将指定数组的指定范围复制到一个新数组。
deepEquals() 如果两个指定数组彼此是深层相等 的,则返回true。
equals() 如果两个指定的 boolean 型数组彼此相等,则返回 true。
fill() 将指定的值分配给指定类型数组的每个元素。
hashCode() 基于指定数组的内容返回哈希码。
sort(char[] a) 对指定的 char 型数组按数字升序进行排序。
toString(int[] a) 返回指定数组内容的字符串表示形式。
1 把数组变成list集合有什么好处?
可以使用集合的思想和方法操作数组中的元素
2 注意:将数组变成集合,不可以使用集合的增删方法。因为数组长度是固定的、
可用 contains get indexOf subList
如果增删,会发生UnsupportedOperationException异常
String[] arr1= {"abc", "dsa","ewtk"};
List<String>list = Arrays.asList(arr1);
System.out.println(list); //[abc, dsa,ewtk] 集合可以直接打印
// 可用list集合的方法判断数组中是否存在某元素。如果用数组,要遍历比较
System.out.println("contains:"+list.contains("cc"));
list.add("qq"); //UnsupportedOperationException
如果数组中的元素都是对象,那么变成集合时,数组中的元素就直接转换成集合中的元素
如果数组中的元素都是基本数据类型,那么会将该数组作为集合中的元素存在
int[] arr3 = {2,4,7};
Listlist1 = Arrays.asList(arr3); // List<int[]> list1 =Arrays.asList(arr3);
System.out.println(list1); //[[I@1c0ec97]
Integer[]arr4 = {2,4,7};
List<Integer> list2 = Arrays.asList(arr4);
System.out.println(list2); //[2, 4, 7]
day17-17-集合(集合转成数组) CollectionToArray
ArrayList<String> a1 = newArrayList<String>();
a1.add("abc1");
a1.add("abc2");
a1.add("abc3");
/*
*1 指定类型的数组到底要定义多长呢?
* 当指定的数组长度小于了集合的size,那么toArray内部会创建一个新数组,长度为集合的size
* 当指定类型的数组长度大于集合的size,就不会创建新数组,空位用null
* 所以创建一个刚刚好的数组最优 【a1.size()】
*
* 2 为什么要将集合变数组?
* 为了限定对元素的操作(增删) 数组再转化为集合时,就不可以使用集合增删方法
*/
String[] arr = a1.toArray(new String[0]); //将集合变数组
System.out.println(Arrays.toString(arr));
day17-18-集合(增强for循环) ForEachDemo
1 支持Iterator迭代的都支持高级for,迭代是Collection特性。Map不支持迭代
2 格式:for(数据类型 变量名 : 被遍历的集合(Collection)或者数组){}
3 对集合进行遍历:只能获取集合元素,但是不能得意集合进行任何操作
迭代器除了遍历:还可以进行remove集合中元素的动作;如果是ListIterator,还可以在遍历的过程中对集合元素进行增删改查的动作
4 传统的for和高级for有什么区别?
高级for有一个局限性,必须要有被遍历的目标
建议在遍历数组的时候,还是用传统for,因为传统for可以定义脚标
ArrayList<String> al = newArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
//加强for循环遍历集合
for(String s :al) //注意:如果集合没加泛型,就不能写String,只能写Obiect
{
//s="kk"; //不能对集合元素操作,但是迭代可以对元素操作,List的迭代器还能增删改
System.out.println(s);
}
//遍历Map集合
HashMap<Integer,String> hm = newHashMap<Integer,String>();
hm.put(1, "a");
hm.put(2, "b");
hm.put(3, "c");
Set<Integer> keySet = hm.keySet(); //获取集合中所有的键的集合
//高级for遍历集合
for(Integer i :keySet)
{
System.out.println(i+"::"+hm.get(i)); //获取键所对的值
}
//获取所有的键值对的集合
//Set<Map.Entry<Integer,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());
}
day17-19-集合(可变参数)
1 JDK1.5版本出现的新特性:方法的可变参数
2 在使用是注意:可变参数一定要定义在参数列表最后面
3 用数组作为参数时虽然少定义(重载)了多个方法,但是每次都要定义一个数组作为实际参数
4 可变参数:其实就是一种数组参数的简写形式。不用每次都手动建立数组对象,只要将操作的元素作为参数传递即可;隐式将这些参数封装成了数组。
5 可变参数一定要定义在参数列表的最后面
public static void show(int ... arr){}
public static void show(String str,int ... arr){}
day17-20-集合(静态导入)
importjava.util.Arrays; //导入Arrays这个类
/*
* 当类名重名时,需要指定具体的包名;
* 当方法重名时,指定具备所属的对象或者类
*/
import staticjava.util.Arrays.*; //导入Arrays这个类中的所有静态成员
import staticjava.lang.System.*; //导入System类中所有静态成员
public class StaticImport
{
public static void main(String[]args)
{
int[] arr = {3,4,1};
sort(arr);
int index = binarySearch(arr,1);
out.println(Arrays.toString(arr));//Object中的和Arrays中的同名方法,所以指定类名
System.out.println("index="+index);
}
}
- 黑马程序员—集合
- 黑马程序员—集合
- 黑马程序员—集合
- 黑马程序员—集合
- 黑马程序员—集合
- 黑马程序员—集合
- 黑马程序员—集合
- 黑马程序员—集合
- 黑马程序员——集合
- 黑马程序员——集合
- 黑马程序员——集合
- 黑马程序员——集合
- 黑马程序员——集合
- 黑马程序员——集合
- 黑马程序员——集合
- 黑马程序员——集合
- 黑马程序员——集合
- 黑马程序员——集合
- 理解Spring的Bean工厂
- NYOJ-最高位数字
- C++通过Sokcet发送结构体到Java
- 串口的配置以及读写
- 8月的最后一天了
- 黑马程序员——集合
- Qt线程
- group by扩展函数之grouping
- 搜网盘地址推荐www.easysoso.cn
- 通过“where's my car”制作初识地图控件(一)
- 冰桶挑战引来了百度搜索冰桶算法
- java注解编程
- Cisco Energywise
- 买股票