------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
Collection
|--List:元素是有序的,元素可以重复。因为该集合体系有索引。
|--ArrayList:底层是数组数据结构,查询速度很快,但是增删稍慢,线程不同步,默认10个元素。(线程不同步)
|--LinkedList:底层是链表数据结构,查询很慢,增删速度很快。(线程不同步)
|--Vector:底层是数组数据结构,和ArrayList一样,查询,增删,都很慢,
Vector是1.0出现,ArrayList是1.2出现,(线程同步)但已经不用了。
|--Set :元素是无序的,元素不可以重复。
|--HashSet:底层数据结构是哈希表。线程是不同步的。
采用散列函数对元素进行排序(Asiic),是专门为快速查询而设计的。
存入HashSet的对象必须定义hashCode方法。
|--LinkedHashSet:有序。
内部使用散列以加快查询速度,同时使用链表维护元素插入的次序,在使用迭代器遍历Set时,
结果会按元素插入的次序显示。
|--TreeSet:底层的数据结构是二叉树。线程是不同步的。
对Set集合中的元素的进行指定(我们指定的比较器)顺序的排序。不同步。TreeSet底层的数据结构就是二叉树。
采用红黑树的数据结构进行排序元素,使用它可以从Set中提取有序(升序或者降序)的序列。
需要注意的是,存入自定义类时,TreeSet需要维护元素的存储顺序,因此自定义类要实现Comparable接口并定义compare
List:
特有方法。凡是可以操作角标的方法都是该体系特有的方法。
增:
add(int index, E element)
在列表的指定位置插入指定元素(可选操作)。
addAll(int index, Collection<? extends E> c)
将指定 collection 中的所有元素都插入到列表中的指定位置(可选操作)。
删:
remove(int index)
移除列表中指定位置的元素(可选操作)。
改:
set(int index, E element)
用指定元素替换列表中指定位置的元素(可选操作)。
查:
get(int index)
返回列表中指定位置的元素。
subList(int fromIndex, int toIndex)
返回列表中指定的 fromIndex(包括 )和 toIndex(不包括)之间的部分视图。
listIterator()
返回此列表元素的列表迭代器(按适当顺序)。
List 集合特有的迭代器。 ListIterator 是 Iterator的子接口。
在迭代器,不可以通过集合对象的方法操作集合中的元素,因为会发生ConcurrentModificationException异常
所以,在迭代器时,只能用迭代器的方法操作元素,可是Iterator的方法是有限的
只能都元素进行,判断,删除,取出的操作。
如果想要其他的操作:如添加,修改等,就需要使用该集合的子接口:ListIterator
该接口只能过过List集合的ListIterator方法获取
*/
public class ListDemo_02 {
public static void method(){
ArrayList al = new ArrayList();
//添加元素
al.add("黑马程序员01");
al.add("黑马程序员02");
al.add("黑马程序员03");
al.add("黑马程序员04");
prt("原集合是:"+al);
//在指定位置添加元素
al.add(3, "哥们我是");
prt("添加后:"+al);
//删除元素
al.remove(3);
prt(al);
//修改元素。
al.set(1, "黑马程序员我必须进");
prt(al);
//通过角标获取元素。
prt(al.get(2));
for(int x=0; x<al.size();x++){
System.out.println("al("+x+")="+al.get(x));
}
/* Iterator it = al.iterator();
while(it.hasNext()){
prt(it.next());
}
*/
for(Iterator it =al.iterator(); it.hasNext();){
prt(it.next());
}
//通过indexOf 获取对象的位置。
prt(al.indexOf("黑马程序员03"));
List sub = al.subList(1, 3);
prt(sub);
}
public static void main(String[] args) {
//演示列表迭代器
ArrayList al = new ArrayList();
//添加元素
al.add("黑马程序员01");
al.add("黑马程序员02");
al.add("黑马程序员03");
al.add("黑马程序员04");
prt(al);
ListIterator li = al.listIterator();//增 删 改 查 都具备 因为他有角标
prt("hasPrevious();"+li.hasPrevious());
while(li.hasNext()){
Object obj = li.next();
if(obj.equals("黑马程序员02")){
// li.add("黑马程序员08");
li.set("黑马哥们我来了");
}
}
//boolean hasPrevious() 如果以逆向遍历列表,列表迭代器有多个元素,则返回 true。
while(li.hasPrevious()){
prt("反向获取:"+li.previous());
}
// prt("hasNext():"+li.hasNext());
// prt("hasPrevious();"+li.hasPrevious());
prt(al);
/* //在迭代过程中,准备添加或者删除元素
Iterator it = al.iterator();//迭代器只能做三个动作 判断 删除 取出
while(it.hasNext()){
Object obj = it.next();
if(obj.equals("黑马程序员02")){
it.remove();//将黑马程序员02的引用中删除了。
// al.add("黑马程序员08");
}
prt("obj="+obj);
}
*/
}
public static void prt(Object obj){
System.out.println(obj);
}
}
package com.itheimaday14;
import java.util.ArrayList;
import java.util.Iterator;
/*
将自定义对象元素存储到ArrayList集合中。并去除重复元素。
比如:存储人对象。同年龄同姓名。视为同一个人。为重复元素。
1,对人类对象描述,将数据都封装进人对象。
2,定义容器,将人存入。
3.取出
List集合判断是否包含其实是根据这个对象判断是否和内部的对象, equals,可以复写这个equals,写自己的判断
当List remove 删除时候,也是i先equals判断有没有,如果所以要注意
*/
class Person01 {
private String name;
private int age;
Person01(String name, int age) {
this.name = name;
this.age = age;
}
public boolean equals(Object obj){
if(!(obj instanceof Person01))
return false;
Person01 p =(Person01)obj;
System.out.println(this.name+"....."+p.name);
return this.name.equals(p.name) && this.age==p.age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class ArrayListTest_07 {
public static void main(String[] args) {
ArrayList lst = new ArrayList();
lst.add(new Person01("谢霆锋", 30));// 存储地址引用!
lst.add(new Person01("谢霆锋", 30));//add(object obj);
//Object obj=new Person("谢霆锋", 30)
lst.add(new Person01("王菲", 27));
lst.add(new Person01("汪峰", 35));
lst.add(new Person01("杨幂", 57));
lst.add(new Person01("杨幂", 57));
lst = singeElement(lst);
Iterator it = lst.iterator();
while (it.hasNext()) {
Person01 p = (Person01) it.next();
prt(p.getName()+"::"+p.getAge());
}
}
public static ArrayList singeElement(ArrayList al){
//定义一个临时容器
ArrayList newAl = new ArrayList();
Iterator it = al.iterator();
while(it.hasNext()){
Object obj = it.next();
if(!newAl.contains(obj)){
newAl.add(obj);
}
}
return newAl;
}
public static void prt(Object obj) {
System.out.println(obj);
}
}
package com.itheimaday14;
import java.util.HashSet;
import java.util.Iterator;
/*
|---Set(集):元素是无序的(存入和取出顺序不一定一致),元素不可以重复。
set集合和Collection功能差不多一样的。
|--HashSet:底层数据结构是哈希表。线程是不同步的。
hash是如何保证元素唯一性的呢?
是通过元素的两个比较方法,hashCode和equals来完成。
如果元素的HashCode值相同,才会判断equals是否为true.
如果元素的HashCode值不同,才会调用equals.
注意,对于判断元素是否存在。以及删除鞥操作。依赖的方法是元素的HashCode和equals方法。
采用散列函数对元素进行排序(Asiic),是专门为快速查询而设计的。存入HashSet的对象必须定义hashCode方法。
|--LinkedHashSet:有序。
内部使用散列以加快查询速度,同时使用链表维护元素插入的次序,在使用迭代器遍历Set时,结果会按元素插入的次序显示。
|--TreeSet:底层的数据结构是二叉树。线程是不同步的。
对Set集合中的元素的进行指定(我们指定的比较器)顺序的排序。不同步。TreeSet底层的数据结构就是二叉树。
采用红黑树的数据结构进行排序元素,使用它可以从Set中提取有序(升序或者降序)的序列。
需要注意的是,存入自定义类时,TreeSet需要维护元素的存储顺序,因此自定义类要实现Comparable接口并定义compare
*/
/*class Demo{
public int hashCode(){
return 60;
}
}*/
public class HashSetDemo_08 {
public static void main(String[] args) {
/*Demo d1 = new Demo();
Demo d2 = new Demo();
prt(d1.toString());
prt(d2);
prt(d1==d2);
prt(d1.equals(d2));*/
HashSet hs = new HashSet();
prt(hs.add("java01"));
hs.add("java02");
prt(hs.add("java03"));
prt(hs.add("java03"));
hs.add("java04");
hs.add("java04");
Iterator it = hs.iterator();
while(it.hasNext()){
prt(it.next());
}
}
public static void prt(Object obj){
System.out.println(obj);
}
}
package com.itheimaday14;
import java.util.*;
/*
*
往HashSet集合中存入自定义对象。
姓名和年龄相同为同一个人。重复元素。
*/
class Person_1
{
private String name;
private int age;
public void setAge(int age) {
this.age = age;
}
Person_1(String name, int age)
{
this.name = name;
this.age =age;
}
public int hashCode()
{
System.out.println(this.name+"..hashCode");
return name.hashCode()+age;
}
public boolean equals (Object obj)
{
if(!(obj instanceof Person_1))
return false;
Person_1 p =(Person_1)obj;
System.out.println(this.name+".equals."+p.name);
return this.name.equals(p.name) && this.age==p.age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
}
public class HashSetTest_09
{
public static void sop(Object obj)
{
System.out.println(obj);
}
public static void main(String[] args)
{
HashSet hs = new HashSet();
hs.add(new Person_1("a1",11));
hs.add(new Person_1("a2",12));
hs.add(new Person_1("a3",13));
hs.add(new Person_1("a2",12));
// hs.add(new Person_1("a4",14));
// sop("al:"+hs.contains(new Person_1("al",11)));
hs.remove(new Person_1("a3",13));
Iterator it = hs.iterator();
while(it.hasNext())
{
Person_1 p = (Person_1)it.next();
sop(p.getName()+": :"+p.getAge());
}
}
}
package com.itheimaday14;
import java.util.HashSet;
import java.util.Iterator;
/*
往HashSet集合中存入自定义对象。
姓名和年龄相同为同一个人。重复元素。
思路:
1,描述一个人的对象
2,输入人对象的属性信息。
3,判断
4,打印输出
*/
//描述一个人类对象
class Person_02 {
private static final Person_02 Object = null;
private String name;
private int age;
Person_02(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
// 判断equals 方法
public boolean equals(Object obj) {
if (!(Object instanceof Person_02)) {
return false;
}
Person_02 p = (Person_02) Object;
return this.name.equals(p.name) && this.age == p.age;
}
// 判断hashCode方法
public int hashCode() {
return name.hashCode() + age * 20;
}
}
public class HashCodeTest_10 {
public static void main(String[] args) {
HashSet hs = new HashSet();
hs.add(new Person_02("王菲", 30));
hs.add(new Person_02("王菲", 30));
hs.add(new Person_02("谢霆锋", 33));
hs.add(new Person_02("刘德华", 42));
prt(hs.contains(new Person_02("谢霆锋01", 32)));
Iterator it = hs.iterator();
while (it.hasNext()) {
Person_02 p = (Person_02) it.next();
prt(p.getName() + ": :" + p.getAge());
}
}
public static void prt(Object obj) {
System.out.println(obj);
}
}
package com.itheimaday15;
import java.util.ArrayList;
import java.util.Iterator;
/*
泛型:JDK 1.5版本以后出现的新特性。用于解决安全问题,是一个安全机制
好处
1,将运行时期出现的问题ClassCastException, 转移到了编译时期。
方便于程序员解决问题。让运行时期问题减少,安全。
2.避免了强制转换的麻烦。
泛型的格式:通过<>来定义要操作的 引用数据类型。
在使用java提供对象时。什么时候写泛型?
通常在集合框架中很常见,
只有见到<E>就要定义泛型。
其实<>就是用来接收类型。
当使用集合时,将集合要存储的数据类型作为参数传递到<>中即可。
*/
public class GennericDemo_01 {
public static void main(String[] args) {
/* int[] arr = new int[3];
arr[0] = 4;
arr[2] = 3.5;*/
ArrayList<String> al = new ArrayList<String>();
al.add("java01");
al.add("java0fd2");
al.add("java0fsdf3");
al.add("java0afd4");
al.add("java02");
// al.add(4);
Iterator<String> it= al.iterator();
while(it.hasNext()){
String s =it.next();
System.out.println(s+":"+s.length());
// System.out.println(it.next());
}
}
}
import java.util.Iterator;
import java.util.TreeSet;
/*
Set:无序,不可重复元素。
|--HashSet:数据结构是哈希表。线程是非同步的。
保证元素唯一性的原理:判断元素的HashCode值是否相同。
如果相同,还会继续 判断元素的equals方法。是否为true.
|--TreeSet: 可以对set中的元素进行排序。
底层数据结构是二叉树。
保证元素的唯一性的依据。
compareTo方法return 0;
TreeSet 排序第一种方法:让元素自身具备比较性。
元素需要实现CompareTo接口,覆盖compareTo方法。
这种方式也称为元素的自然顺序。或者叫做默认顺序。
TreeSet 第二种排序。
当元素自身不具备比较性时。或者具备的比较性不是所需要的。
这时需要让集合自身具备比较性。
在集合初始化时,就有了比较方式。
报错:提示(Exception in thread "main" java.lang.ClassCastException:
(TreeSet 排序第一种方法:让元素自身具备比较性。)
com.theimaday15.Student cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1290)
at java.util.TreeMap.put(TreeMap.java:538)
at java.util.TreeSet.add(TreeSet.java:255)
at com.theimaday15.TreeSetDemo_01.main(TreeSetDemo_01.java:73)
)
需求:
往 TreeSet集合中存储自定义对象学生。
想按学生的年龄进行排序。
记住:排序时,当主要条件相同时。一定要判断次要条件。
*/
class Student implements Comparable {// 该接口强制让学生具备比较性
private String name;
private int age;
Student(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return 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) {
return this.name.compareTo(s.name);
}
return -1;
}
}
public class TreeSetDemo_01 {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Student("lisi02", 22));
ts.add(new Student("lisi0222", 32));
ts.add(new Student("lisi0122", 19));
ts.add(new Student("lisi042", 19));
Iterator it = ts.iterator();
while (it.hasNext()) {
Student stu = (Student) it.next();
System.out.println((stu.getName() + "..." + stu.getAge()));
}
}
}
package com.itheimaday15;
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
/*
当元素自身不具备比较性,或者具备的比较性不是所需要的。
这时需要让容器自身具备比较性。
定义了编辑器。将比较器对象作为参数传递;
当两种排序都存在时, 以比较器为主。
定义一个类。实现comparator接口,覆盖compare方法。
都是以return 0判断元素是否相同;
*/
class Student_1 {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
Student_1(String name, int age) {
this.name = name;
this.age = age;
}
}
public class TreeSetDemo_02 {
public static void main(String[] args) {
TreeSet ts = new TreeSet();
ts.add(new Student("lisi02", 06));
ts.add(new Student("lisi0222", 32));
ts.add(new Student("lisi0122", 19));
ts.add(new Student("lisi042", 19));
Iterator it = ts.iterator();
while (it.hasNext()) {
Student stu = (Student) it.next();
System.out.println((stu.getName() + "..." + stu.getAge()));
}
}
}
class MyCopar implements Comparator{
public int compare(Object o1, Object o2) {
Student_1 s1 = (Student_1)o1;
Student_1 s2 = (Student_1)o2;
int num = s1.getName().compareTo(s2.getName());
if (num == 0) {
return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
}
return num;
}
}
package com.itheimaday16;
import java.util.Collection;
import java.util.HashMap;
/*
Map集合:该集合存储建值对,一对一对往里存,而且保证建的唯一性
1,添加:
put(K key, V value)
将指定的值与此映射中的指定键关联(可选操作)。
putAll(Map<? extends K,? extends V> m)
从指定映射中将所有映射关系复制到此映射中(可选操作)。
2,删除
clear()
从此映射中移除所有映射关系(可选操作)。
remove(Object key)
如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
3,判断
containsKey(Object key)
如果此映射包含指定键的映射关系,则返回 true。
containsValue(Object value)
如果此映射将一个或多个键映射到指定值,则返回 true。
isEmpty()
如果此映射未包含键-值映射关系,则返回 true。
4,获取
get(Object key)
返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
size()
返回此映射中的键-值映射关系数。
values()
返回此映射中包含的值的 Collection 视图。
entrySet()
返回此映射中包含的映射关系的 Set 视图。
keySet()
返回此映射中包含的键的 Set 视图。
Map
|--Hashtable:底层是哈希表数据结构,不可以存入null键null值。该集合是线程同步的。JDK1.0.效率低。
此类实现一个哈希表,该哈希表将键映射到相应的值。任何非null 对象都可以用作键或值。
为了成功地在哈希表中存储和获取对象,用作键的对象必须实现 hashCode 方法和 equals 方法。
|--HashMap:基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用null 值和null键。
(除了非同步和允许使用null 之外,HashMap 类与Hashtable 大致相同。)此类不保证映射的顺序,
特别是它不保证该顺序恒久不变。 将 Hashtable替代,JDK1.2.效率高。
|--TreeMap:基于红黑树(Red-Black tree)的 NavigableMap 实现。该映射根据其键的自然顺序进行排序,
或者根据创建映射时提供的 Comparator(比较器) 进行排序,具体取决于使用的构造方法。
和Set很像。其实大家,Set底层就是使用了Map集合。线程不同步。可以用于给Map集合中的键进行排序。
*/
public class MapDemo_01 {
public static void main(String[] args) {
HashMap<String,String> map= new HashMap<String,String>();
//添加元素,如果出现相同的建,那么后添加的值会覆盖原有键对应值,并put方法会返回被覆盖的值。
System.out.println(map.put("01", "张三1"));
System.out.println(map.put("01", "张三01"));//新的值会替换老的值。
map.put("02", "张三2");
map.put("08", "张三3");
map.put("04", "张三4");
prt("containsKey:"+map.containsKey("088"));
// prt("remove:"+map.remove("02"));
prt("get:"+map.get("02"));
map.put(null, "aaa");
prt("get"+map.get(null));
//可以通过get方法的返回值来判断一个键是否存在。。通过返回空来判断
//获取map集合中所有的值。
Collection<String> coll = map.values();
prt(coll);
prt(map);
}
public static void prt(Object obj){
System.out.println(obj);
}
}
import java.util.*;
/*
map集合的两种取出方式:
1.Set<k>getSet:将map中所有的键存入到Set集合。因为Set具备迭代器。所有可以迭代方式取出所有的键,
在根据get方法。获取每一个键对象的值。
Map集合的取出原理:将map集合转成Set集合。在通过迭代器取出。
2.Set<Map.Entry<k,v>>entrySet:将map集合中的映射关系存入到了set集合中,
而这个关系的数据类型就是:Map.Entry
Set<Map.Entry<K,V>> entrySet()
返回此映射所包含的映射关系的 Set 视图。
将Map集合中的映射关系存入到了set集合中,而这个关系的数据类型就是:Map.Entry
entrySet():将Map集合中的映射关系取出。
这个关系就是 Map.Entry 类型
那么关系对象 Map.Entry 获取到后,就可以通过,Map.Entry中getKey和getValue方法获取关系中的键和值
Map.Entry 其实Entry也是一个接口,她是接口中的一个内部接口。
(内部规则)
interface Map{
public static interface Entry{
public abstract Object getKey();
public abstract Object getValue();
}
}
class HashMap implement Map.Entry{
class haha implements Map.Entry{
public abstract Object getKey();
public abstract Object getValue();
}
}
*/
public class MapDemo_02 {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<String,String>();
map.put("01", "zhangsan01");
map.put("05", "zhangsan05");
map.put("04", "zhangsan03");
map.put("02", "zhangsan07");
//将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());
String key = me.getKey();
String value = me.getValue();
prt("key:"+key+" value:"+value);
}
}
/* //先获取map集合的所有键的set集合, keySet();
Set<String> ks = map.keySet();
//有 了set集合,就可以获取其迭代器。
prt(ks);
Iterator<String> it = ks.iterator();
while(it.hasNext()){
String key = it.next();
//有了建就可以通过map集合的get方法获取其对应的值。
;
String value = map.get(key);
prt("key:"+key+",value:"+value);
}
}*/
public static void prt(Object obj){
System.out.println(obj);
}
}
package com.itheimaday16;
import java.util.*;
import java.util.Map.Entry;
/*
每一个学生读有对应的归属地。
学生Student, 地址String.
学生属性:姓名,年龄。
注意:姓名和年龄相同的视为同一个学生。
保证学生的唯一性。
1.描述学生。
2.定义map 容器。将学生作为键,地址作为值。存入。
3.获取map集合中的元素。
*/
class Student implements Comparable<Student> {
private String name;
private int age;
public int hashCode() {
return this.name.hashCode() + this.age * 27;
}
public boolean equals(Object obj) {
if (!(obj instanceof Student)) {
throw new ClassCastException("类型不匹配");
}
Student s = (Student) obj;
return this.name.equals(s.getName()) && this.age == s.age;
}
public int compareTo(Student s) {
int num = new Integer(this.age).compareTo(new Integer(s.age));
if (num == 0) {
num = this.name.compareTo(s.name);
}
return num;
}
Student(String name, int age) {
this.name = name;
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return age;
}
public String toString() {
return this.name + ":" + this.age;
}
}
public class MapTest_03 {
public static void main(String[] args) {
HashMap<Student, String> hm = new HashMap<Student, String>();
hm.put(new Student("zhangsan", 25), "shanghai");
hm.put(new Student("lisi", 25), "beijing");
hm.put(new Student("wangwu", 20), "shanghai");
hm.put(new Student("zhouyang", 25), "shanghai");
hm.put(new Student("zhouyang", 25), "shanghai");
// 第一种取出方式 keySet
/*
Set<Student> stu = hm.keySet();
Iterator<Student> it = stu.iterator();
while (it.hasNext()) {
Student key = it.next();
String value = hm.get(key);
System.out.println(key + ":" + value);
}*/
//第二种取出方式 EntrySet
Set<Map.Entry<Student, String>> entry = hm.entrySet();
Iterator<Map.Entry<Student, String>> it = entry.iterator();
while(it.hasNext()){
Map.Entry<Student, String> me =it.next();
Student key = me.getKey();
String addr = me.getValue();
System.out.println(key+"___"+addr);
}
}
}
package com.itheimaday16;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/*
练习:
“aaabfcdabcef”
获取该字符串中的字母出现的次数。
希望打印的 结果:a(1)....
通过结果发现,每一个字母都有对应的次数。
说明字母和次数之间都有映射关系。
注意了。当发现映射关系时,可以选择map集合。
因为map集合中存放就是映射关系。
什么时候使用map集合呢?
当数据之间存在映射关系时,就要先想到map集合。
思路:
1.将字符串转换成字符数组。因为要对每一个字母进行操作。
2.定义一个map集合,因为打印结果的字母有 顺序。所以使用treeMap集合.
3.遍历字符数组。
将每一个字母作为建去查map集合。
如果返回null,将该字母和1存入到map集合中。
如果返回不是null,说明该字母在map集合中已经存在.并有对应的次数。
那么久获取该次数并进行自增。然后将该字母和自增后的次数存入到map集合中,
覆盖调用原有的建所对应的值。
4.将map 集合中的数据变成指定的字符串形式返回。
*/
public class MapTest_05 {
public static void main(String[] args) {
String s = "aaabffdsfdscdabcef";
System.out.println(charConnts(s));
}
public static String charConnts(String str) {
// 将字符串转为数组;
char[] chs = str.toCharArray();
// 定义一个treemap集合容器
TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
// 将数组遍历 判断并存入集合中
for (int x = 0; x < chs.length; x++) {
if (!((chs[x] >= 'a' && chs[x] <= 'z') || (chs[x] >= 'A' && chs[x] <= 'Z')))
continue;
Integer value = tm.get(chs[x]);
if (value == null) {
tm.put(chs[x], 1);
} else {
value = value + 1;
tm.put(chs[x], value);
}
}
// 定义一个缓冲区容器存储元素
StringBuilder sb = new StringBuilder();
// Entry.Set 迭代treemap
Set<Map.Entry<Character, Integer>> et = tm.entrySet();
Iterator<Map.Entry<Character, Integer>> it = et.iterator();
while (it.hasNext()) {
Map.Entry<Character, Integer> me = it.next();
Character key = me.getKey();
Integer value = me.getValue();
sb.append(key + "(" + value + ")");
}
return sb.toString();
}
}
package com.itheimaday16;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
/*
Map扩展知识。
Map结合被使用,是因为具备映射关系。
一个学校,每个学校都有班级,班级都有名称
一个学校-->教室-->学生
*/
public class MapTest_06 {
public static void main(String[] args) {
HashMap<String, String> yure = new HashMap<String, String>();
yure.put("01", "zhans");
yure.put("02", "lisi");
HashMap<String, String> jiuye = new HashMap<String, String>();
jiuye.put("05", "wangwu");
jiuye.put("09", "zhaoliou");
HashMap<String, HashMap<String, String>> czbk = new HashMap<String, HashMap<String, String>>();
czbk.put("yure", yure);
czbk.put("jiuye", yure);
// 遍历czbk集合。获取所有的教室。
Set<String> str = czbk.keySet();
Iterator<String> it = str.iterator();
while (it.hasNext()) {
String roomName = it.next();
HashMap<String, String> room = czbk.get(roomName);
getStudentInfo(room);
// prt(roomName);
}
// getStudentInfo(yure);
// getStudentInfo(jiuye);
}
public static void getStudentInfo(HashMap<String, String> rooMap) {
Iterator<String> it = rooMap.keySet().iterator();
while (it.hasNext()) {
String id = it.next();
String name = rooMap.get(id);
prt(id + ":" + name);
}
}
public static void prt(Object obj) {
System.out.println(obj);
}
}
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/*
高级for循环:
格式:
for(数据类型 变量名:被遍历的集合(Collection)或者数组){
}
对集合遍历。
只能获取元素,但是不能对集合进行操作。
迭代器除了遍历。还可以进行remove集合中元素的动作。
如果使用 Iterator, 还可以在遍历的过程中对集合进行增除改查;
传统for和高级for有什么区别?
高级for有一个局限性。必须有被遍历的目标。
建议在遍历数组的时候,还是希望使用传统for.因为可以定义角标。(因为数组的操作大部分是对角标的操作)
*/
public class ForEachDemo_06 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<String>();
list.add("黑马程序员001");
list.add("黑马程序员002");
list.add("黑马程序员008");
list.add("黑马程序员004");
Iterator<String> it = list.iterator();
// 数据类型 变量名:被遍历的集合(Collection)或者数组
for (String s : list) {// 1.5版本出现 简化书写 爽!!!
s = "kkk";// 改变不了集合中的元素。不能作操作。
// prt(s);
}
// prt(list);
/*
* while (it.hasNext()) {
*
* String str = it.next();
*
* prt(str);
*
* }
*/
int[] arr = { 3, 5, 8 };
for (int i : arr) {
// prt(i);
}
HashMap<Integer, String> map = new HashMap<Integer,String>();
map.put(1, "dfds");
map.put(5, "sdds");
map.put(2, "dfds");
map.put(6, "fdsp");
map.put(8, "nihao");
/* Set<Integer> keySet = map.keySet();
for( Integer i:keySet)
prt(i+map.get(i));*/
Set<Map.Entry<Integer, String>> etry =map.entrySet();
for(Map.Entry<Integer, String> me:etry){
Integer key = me.getKey();
String value = me.getValue();
prt(key+","+value);
}
}
public static void prt(Object obj) {
System.out.println(obj);
}
}
/*
JDK1.5版本出现的新特性。
可变参数的方法时:
在使用是注意:可变参数一定要定义在参数列表的最后面!
*/
public class ParamMethodDemo_07 {
public static void main(String[] args) {
/* int[] arr= {3,4};
*
*虽然少定义了多个方法。
*
*但是每次都要定义一个数组。作为时间参数
show(arr);
int[] arr1 ={13131,464,54};
show(arr1);
*/
/*
可变参数。
其实就是上一种参数的简写形式。
不用每一次都手动的建立数组对象。
只要将要操作的元素作为参数传递即可。
隐式将这些参数封装成了数组。
*/
show("dsfds",2,55,646,3,56);
show("a",2,55,44,646,3,56);
show("");
// show(3,4);
}
public static void show(String str,int ...arr){
System.out.println(arr);
System.out.println(arr.length);
}
// public static void show(int[] arr){}
/*public static void show(int a, int b){
System.out.println(a+","+b);
}
public static void show(int a, int b,int c){}*/
}
import java.util.Arrays;
import static java.util.Arrays.*;//导入Arrays这个类中的所有静态方法。
import static java.lang.System.*;//导入System这个类中的所有静态成员。
/**
StaticImport 静态导入。
当类名重名时。需要指定具体的包名。
当方法重名。指定具体所属的对象或者类。
* @author ZY
*
*
*
/*
packa/Demo.class
packb/Demo.class
import packa.*;
import packb.*;
new Demo();
*/
public class StaticImport_08 {
public static void main(String[] args) {
int [] arr = {3,1,8,};
sort(arr);
int index = binarySearch(arr, 1);
out.println(Arrays.toString(arr));
out.println(index);
}
}
集合体系总结:
Collection(单列)
List(有序,可重复)
Set(无序,唯一)
ArrayList: 底层数据结构是数组,查询快,增删慢。线程不同步,效率高。
LinkedList:底层数据结构是链表,查询慢,增删快。线程不同步,效率高。
Vector: 底层数据结构是数组,查询快,增删慢。线程同步,效率低。
HashSet:底层数据结构是哈希表。线程不同步,效率高。 怎么保证唯一性的呢?它依赖两个方法:hashCode()和equals()顺序:首先判断hashCode()值是否相同。同:继续走equals(),看返回值如果true:就不添加到集合。如果false:就添加到集合。不同:就添加到集合。
TreeSet:底层数据结构是二叉树。 线程不同步,效率高。 怎么保证唯一性的呢?是根据返回是否是0。
怎么保证排序的呢?两种方式
一、自然排序(元素具备比较性) 实现Comparable接口
二、比较器排序(集合具备比较性) 实现Comparator接口
Map(双列 底层结构是针对键有效,跟值无关)
HashMap:底层数据结构是哈希表。线程不同步,效率高。
怎么保证唯一性的呢?
它依赖两个方法:hashCode()和equals()顺序:首先判断hashCode()值是否相同。同:继续走equals(),看返回值如果true:就不添加到集合。如果false:就添加到集合。不同:就添加到集合。
Hashtable:底层数据结构是哈希表。线程安全,效率低。
怎么保证唯一性的呢?
它依赖两个方法:hashCode()和equals()顺序:首先判断hashCode()值是否相同。同:继续走equals(),看返回值如果true:就不添加到集合。如果false:就添加到集合。不同:就添加到集合。
TreeMap:底层数据结构是二叉树。线程不同步,效率高。
怎么保证唯一性的呢?是根据返回是否是0。
怎么保证排序的呢?两种方式自然排序(元素具备比较性)实现Comparable接口比较器排序(集合具备比较性)实现Comparator接口
集合常见应用功能
(添加功能,判断功能,删除功能,获取功能,长度功能)