集合五大接口:Collection,Set,List,Map,Iterable
Collection接口:定义了存取一组对象的方法,其子接口Set,List定义了存储方式。
Set中的数据对象没有顺序不可重复。List中的数据对象有顺序也可重复。Map--->键值映射对。
public static void main(String[] args) throws ParseException{
//通过接口来定义,这样更换具体类如arraylist->linkedlist,无需更改后面的方法。它们都实现的同一接口。
List list=new ArrayList(); //ArrayList中有一个Object[] elementData
List list2=new LinkedList(); //底层实现为链表,arraylist底层实现为数组,一般用arraylist,数组查询快嘛
//Vector:底层用数组实现,但是线程安全的。效率低。arrayList,linkedList线程不安全,效率高.
//如果需要多个线程共享的话,用Vector,但一般我们定义成局部变量,跟线程没有关系。使用arrayList就可以了。
List list4=new Vector();
Collection c=new ArrayList(); //里面方法比list少
list.add("eee");
list.add(11234);
list.add(new Date());
out.println(list.size()); //为3
List list3=new ArrayList();
list2.add("44444");
list2.add("dddd");
list.add(list2);
out.println(list.size()); //为4
String str=(String)list.get(0); //里面都是object,需要强转
list.set(0, "33333");
list.remove(0);
list.remove(new Date()); //判断是否为同一个对象:hashcode,equals
}
实现自己的arrayList::::::::::::::
/**
* 自己实现一个ArrayList,帮助我们更好的理解ArrayList类的底层结构!
*
*/
public class SxtArrayList /*implements List*/ {
private Object[] elementData;
private int size;
public int size(){
return size;
}
public boolean isEmpty(){
return size==0;
}
public SxtArrayList(){
this(10);
}
public SxtArrayList(int initialCapacity){
if(initialCapacity<0){
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
elementData = new Object[initialCapacity];
}
public void add(Object obj){
//数组扩容和数据的拷贝
if(size==elementData.length){
Object[] newArray = new Object[size*2+1];
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
// for(int i=0;i<elementData.length;i++){
// newArray[i] = elementData[i];
// }
elementData = newArray;
}
elementData[size++]=obj;
// size++;
}
public Object get(int index){
rangeCheck(index);
return elementData[index];
}
public void remove(int index){
rangeCheck(index);
//删除指定位置的对象
//a b d e
int numMoved = size - index - 1;
if (numMoved > 0){
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
}
elementData[--size] = null; // Let gc do its work
}
public void remove(Object obj){
for(int i=0;i<size;i++){
if(get(i).equals(obj)){ //注意:底层调用的equals方法而不是==.
remove(i);
}
}
}
public Object set(int index,Object obj){
rangeCheck(index);
Object oldValue = elementData[index];
elementData[index] = obj;
return oldValue;
}
public void add(int index,Object obj){
rangeCheck(index);
ensureCapacity(); //数组扩容
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = obj;
size++;
}
private void ensureCapacity(){
//数组扩容和数据的拷贝
if(size==elementData.length){
Object[] newArray = new Object[size*2+1];
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
// for(int i=0;i<elementData.length;i++){
// newArray[i] = elementData[i];
// }
elementData = newArray;
}
}
private void rangeCheck(int index){
if(index<0||index>=size){
try {
throw new Exception();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
SxtArrayList list = new SxtArrayList(3);
list.add("333");
list.add("444");
list.add("5");
list.add("344433");
list.add("333");
list.add("333");
System.out.println(list.size());
// System.out.println(list.get(6));
list.remove("444");
System.out.println(list.size());
}
}
自己实现一个LinkedList(双向链表)::::::
//用来表示一个节点
public class Node {
Node previous; //上一个节点
Object obj;
Node next; //下一个节点
public Node() {
}
public Node(Node previous, Object obj, Node next) {
super();
this.previous = previous;
this.obj = obj;
this.next = next;
}
public Node getPrevious() {
return previous;
}
public void setPrevious(Node previous) {
this.previous = previous;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
//用来表示一个节点
public class Node {
Node previous; //上一个节点
Object obj;
Node next; //下一个节点
public Node() {
}
public Node(Node previous, Object obj, Node next) {
super();
this.previous = previous;
this.obj = obj;
this.next = next;
}
public Node getPrevious() {
return previous;
}
public void setPrevious(Node previous) {
this.previous = previous;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
public Node getNext() {
return next;
}
public void setNext(Node next) {
this.next = next;
}
}
实现Map接口的类用来存储:key-value。Map接口的实现有:HashMap,TreeMap ..Map类中的key值不能重复。
Map下的实现类特别多:关注HashMap,HashTable
HashMap效率高,线程不安全。HashTable线程安全,效率低。
Map map=new HashMap();
map.put("time", new Date());
map.put("time2", System.currentTimeMillis());
Date date=(Date)map.get("time");
boolean f=map.containsKey("time");
/**
*自定义实现Map的功能!
*暂不完美!
*Map:存放键值对,根据键对象找对应的值对象.键不能重复!
*
*/
public class SxtMap001 {
SxtEntry[] arr = new SxtEntry[990];
int size;
public void put(Object key,Object value){
SxtEntry e = new SxtEntry(key,value);
//解决键值重复的处理
for(int i=0;i<size;i++){
if(arr[i].key.equals(key)){
arr[i].value=value;
return ;
}
}
arr[size++] = e;
}
public Object get(Object key){
for(int i=0;i<size;i++){
if(arr[i].key.equals(key)){
return arr[i].value;
}
}
return null;
}
public boolean containsKey(Object key){
for(int i=0;i<size;i++){
if(arr[i].key.equals(key)){
return true;
}
}
return false;
}
public boolean containsValue(Object value){
for(int i=0;i<size;i++){
if(arr[i].value.equals(value)){
return true;
}
}
return false;
}
public static void main(String[] args) {
SxtMap001 m = new SxtMap001();
m.put("高琪", new Wife("杨幂"));
m.put("高琪", new Wife("李四"));
Wife w = (Wife) m.get("高琪");
System.out.println(w.name);
}
}
class SxtEntry {
Object key;
Object value;
public SxtEntry(Object key, Object value) {
super();
this.key = key;
this.value = value;
}
}
/**
* 自定义Map的升级版:
* 1. 提高查询的效率
*
*
*/
public class SxtMap002 {
LinkedList[] arr = new LinkedList[9]; //Map的底层结构就是:数组+链表! 使用哈希算法实现。
int size;
public void put(Object key,Object value){
SxtEntry e = new SxtEntry(key,value);
int a = key.hashCode()%arr.length; //对象的hashCode是按内存地址来确定的。内存地址是唯一的。
if(arr[a]==null){
LinkedList list = new LinkedList();
arr[a] = list;
list.add(e);
}else{
LinkedList list = arr[a];
for(int i=0;i<list.size();i++){
SxtEntry e2 = (SxtEntry) list.get(i);
if(e2.key.equals(key)){
e2.value = value; //键值重复直接覆盖!
return;
}
}
arr[a].add(e);
}
//a:1000-->1 b:10000-->13
}
public Object get(Object key){
int a = key.hashCode()%arr.length;
if(arr[a]!=null){
LinkedList list = arr[a];
for(int i=0;i<list.size();i++){
SxtEntry e = (SxtEntry) list.get(i);
if(e.key.equals(key)){
return e.value;
}
}
}
return null;
}
public static void main(String[] args) {
SxtMap002 m = new SxtMap002();
m.put("高琪", new Wife("杨幂"));
m.put("高琪", new Wife("李四"));
Wife w = (Wife) m.get("高琪");
System.out.println(w.name);
}
}
Collection类对象在调用remove,contain方法时,需要比较对象是否相等,这会涉及到对象类型的equals方法和hashcode方法。对于自定义的类型,需要重写equals和hashcode以实现自定义的对象相等规则。
注意:JAVA中规定对于内容相同的对象应当具有相等的hashcode。
hashcode就相当于桶,只有在hashcode相等的前提下才会调用equals方法。所以一般要重写hashcode和equals方法. 要重写的话两个都要重写,要保证如果equals为true的时候,hashcode一定要相等.
重写的时候可以利用工具自动生成,像getter,setter方法一样.会让你选择依据哪些属性来生成hashcode和equals方法.
也可以直接看String 或其它类的重写equals,hashcode方法.还是写的非常精妙的.
hashMap的键不能够重复的意思就是说:调用equals方法的结果是否为true
String a=new String("aaa");
String b=new String("aaa");
Map m=new HashMap();
m.put(a,"aaa");
m.put(b,"bbb"); //b与a的equals方法结果为true,故会覆盖a的值.
Set集合也是一样的,里面的内容是不能重复的,也是通过equals方法返回true 来判断的.
总之,如果hashCode相等,equals不一定为true,equals方法为true,则hashcode值一定相等.hashCode与equals一般不需要你重写.
双向链表访问指定位置的元素值:与链表大小的一半来比较,来确定从前往后走还是从后往前走.这个张亚leader面试时还问过我.
后来看了linkedlist的源码,它的除二操作通过向右移一位来做,效率非常高.值得学习.
Node<E> node(int index){
if(index < (size>>1)){
Node<E> x=first;
for(int i=0;i<index;i++){x=x.next}
return x;
}else{}
}
hashCode再得出之后有可能是负值,这是另一个细节,做一个判断即可,让它不为负值.
Set是Collection接口的子接口,没有顺序,不可重复.实现类有:HashSet,TreeSet等.
hashSet的底层实现是通过hashMap,
Set set = new HashSet();
set.add("aaa");
set.add("bbb");
set.add(new String("aaa"));
System.out.println(set.size());//2
System.out.println(set.contains("aaa"));//true
set.remove("aaa");
/**
* 自定义自己的HashSet
* @author Administrator
*
*/
public class SxtHashSet {
HashMap map;
private static final Object PRESENT = new Object();
public SxtHashSet(){
map = new HashMap();
}
public int size(){
return map.size();
}
public void add(Object o){
map.put(o, PRESENT); //set的不可重复就是利用了map里面键对象的不可重复!
}
public static void main(String[] args) {
SxtHashSet s = new SxtHashSet();
s.add("aaa");
s.add(new String("aaa"));
System.out.println(s.size());
}
}
Set下有很多子类,都是底层实现的不同,如TreeSet底层就是通过树来实现的.
//一个map对象对应一行记录!!!
Map map = new HashMap();
map.put("id", 0301);
map.put("name", "高琪");
map.put("salary", 3050);
map.put("department","项目部");
map.put("hireDate", "2007-10");
Map map2 = new HashMap();
map2.put("id", 0302);
map2.put("name", "马士兵");
map2.put("salary", 3500);
map2.put("department","教学部");
map2.put("hireDate", "2006-10");
Map map3 = new HashMap();
map3.put("id", 0302);
map3.put("name", "裴新");
map3.put("salary", 3500);
map3.put("department","教学部");
map3.put("hireDate", "2006-10");
List<Map> list = new ArrayList<Map>();
list.add(map);
list.add(map2);
list.add(map3);
通过map或者通过javabean的方式都很常用.都需要掌握.
Iterator接口:
所有实现了Collection接口的类都有一个iterator方法用以返回一个实现了Iterator接口的对象.即迭代器,用以方便的对容器内的对象进行遍历.它有3个方法:hasNext(),next(),remove()
List list = new ArrayList();
list.add("aaa");
list.add("bbb");
list.add("ccc");
//通过索引遍历List
for(int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
//通过迭代器遍历List
for(Iterator iter2 = list.iterator();iter2.hasNext();){
String str = (String) iter2.next();
System.out.println(str);
iter2.remove(); //删除刚刚遍历的对象
iter2.remove();//连接调用两次会抛出异常,具体可看源码
}
System.out.println(list.size()+"******");
Set set = new HashSet();
set.add("高1");
set.add("高2");
set.add("高3");
//通过迭代器遍历Set
// Iterator iter = set.iterator();
// while(iter.hasNext()){
for(Iterator iter = set.iterator();iter.hasNext();){
String str = (String) iter.next();
System.out.println(str);
}
}
Map map = new HashMap();
map.put("aa", "aaaa");
map.put("bb", "bbbb");
//遍历Map的第一种方式
Set keys = map.keySet();
for(Iterator iter = keys.iterator();iter.hasNext();){
String keyStr = (String) iter.next();
System.out.println(keyStr+"---"+map.get(keyStr));
}
//遍历Map的第二种方式
Set<Entry> set2 = map.entrySet();
for(Iterator iter = set2.iterator();iter.hasNext();){
Entry e = (Entry) iter.next();
System.out.println(e.getKey()+"---"+e.getValue());
}
}
泛型:参数化类型,使用广泛.
起因:数据类型不明确,装入数据的类型都被当作object,从而丢失了自己的实际类型,获取数据往往需要转型,效率低,容易产生错误.
优点:在编译的时候检查类型安全,所有的强制转换都是自动和隐式的,提高代码的重用率.
泛型常见字母:T表示类型, KV表示键值中的key,value. E代表element. ?代表不确定的类型.
泛型类:定义类时使用泛型,格式<>
class 类名<字母列表>{
修饰符 字母 属性;
修饰会 构造器(字母){}
修饰符 返回类型 方法(字母){}
}
泛型不能使用在静态方法,静态属性上.
/**
* 泛型类:声明时使用泛型
* 字母:
* T Type 表示类型。
K V 分别代表键值中的Key Value。
E 代表Element。
使用时确定类型
注意:
1、泛型只能使用引用类型,不能基本类型
2、泛型声明时字母不能使用 静态属性|静态方法上
* @author Administrator
*
* @param <T>
*/
public class Student<T1,T2> {
private T1 javaScore;
private T2 oracleScore;
//泛型声明时不能使用 静态属性|静态方法上
//private static T1 test;
public T1 getJavaScore() {
return javaScore;
}
public void setJavaScore(T1 javaScore) {
this.javaScore = javaScore;
}
public T2 getOracleScore() {
return oracleScore;
}
public void setOracleScore(T2 oracleScore) {
this.oracleScore = oracleScore;
}
/**
* @param args
*/
public static void main(String[] args) {
//使用时指定类型(引用类型)
Student<String,Integer> stu = new ();
//1、安全:类型检查
stu.setJavaScore("优秀");
//2、省心:类型转换
int it =stu.getOracleScore(); //自动拆箱
}
}
/**
* 接口中 泛型字母只能使用在方法中,不能使用在全局常量中
* @author Administrator
*
* @param <T>
*/
public interface Comparator<T> {
void compare(T t);
}
泛型方法: 要定义方法,只需要将泛型参数列表置返回值前.
修饰符 <字母> 返回类型 方法名(字母){
}
泛型还可以定义在方法中,与其所在的类是否泛型没有关系.
/**
* 泛型方法 <> 返回类型前面
* 只能访问对象的信息,不能修改信息
* @author Administrator
*
*/
public class TestMethod {
/**
* @param args
*/
public static void main(String[] args) {
test("a"); //T -->String
}
//泛型方法
public static <T> void test(T a){
System.out.println(a);
}
// extends <=
public static <T extends Closeable> void test(T... a){
for(T temp:a){
try {
if(null!=temp){
temp.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
子类与父类|接口一样使用泛型,子类指定具体的类型,子类与父类|接口同时擦除类型,子类泛型,父类|接口擦除.
错误:子类擦除,父类泛型. 擦除统一使用object对待.
/**
* 父类为泛型类
* 1、属性
* 2、方法
*
* 要么同时擦除,要么子类大于等于父类的类型,
* 不能子类擦除,父类泛型
* 1、属性类型
* 父类中,随父类而定
* 子类中,随子类而定
* 2、方法重写:
* 随父类而定
*
*
* @author Administrator
*
* @param <T>
*/
public abstract class Father<T,T1> {
T name;
public abstract void test(T t);
}
/**
* 子类声明时指定具体类型
* 属性类型为具体类型
* 方法同理
*/
class Child1 extends Father<String,Integer>{
String t2;
@Override
public void test(String t) {
}
}
/**
* 子类为泛型类 ,类型在使用时确定
* @author Administrator
*
*/
class Child2<T1,T,T3> extends Father<T,T1>{
T1 t2;
@Override
public void test(T t) {
}
}
/**
* 子类为泛型类,父类不指定类型 ,泛型的擦除,使用Object替换
*/
class Child3<T1,T2> extends Father{
T1 name2;
@Override
public void test(Object t) {
// TODO Auto-generated method stub
}
}
/**
* 子类与父类同时擦除
*/
class Child4 extends Father{
String name;
@Override
public void test(Object t) {
}
}
/**
*错误:子类擦除,父类使用泛型
class Child5 extends Father<T,T1>{
String name;
@Override
public void test(T t) {
}
*/
/**
* 泛型接口:与继承同理
* 重写方法随父类而定
*
* @param <T>
*/
public interface Comparable<T> {
void compare(T t);
}
//声明子类指定具体类型
class Comp implements Comparable<Integer>{
@Override
public void compare(Integer t) {
// TODO Auto-generated method stub
}
}
//擦除
class Comp1 implements Comparable{
@Override
public void compare(Object t) {
// TODO Auto-generated method stub
}
}
//父类擦除,子类泛型
class Comp2<T> implements Comparable{
@Override
public void compare(Object t) {
// TODO Auto-generated method stub
}
}
//子类泛型>=父类泛型
class Comp3<T> implements Comparable<T>{
@Override
public void compare(T t) {
// TODO Auto-generated method stub
}
}
//父类泛型,子类擦除 错误
public static void main(String[] args) {
Student stu1 = new Student();
//消除警告 使用 Object
Student<Object> stu = new Student<Object>(); //这个不叫擦除,指定了一个具体的类型Object
//stu.setJavaScore("af"); //以Object对待
test(stu1); //stu1 相当于Object 但是不完全等同Object
//擦除,不会类型检查
//test(stu); //报错,但上一条不会报错.
test1(stu1);
test1(stu);
}
public static void test(Student<Integer> a){
}
public static void test1(Student<?> a){
}
泛型没有多态:
通配符:? extends super
/**
* 通配符
* ?类型不定,使用时确定类型
* ?使用:声明类型|声明方法上,不能声明类或使用时
* ? extends : <= 上限 指定类型 子类或自身
* ? super :>=下限 指定类型 为自身或父类
* @author Administrator
*
*/
public class Student<T> {
T score;
public static void main(String[] args) {
Student<?> stu = new Student<String>();
test(new Student<Integer>());
test2(new Student<Apple>());
//test3(new Student<Apple>()); //泛型没有多态,这个丢不进去,会出错的.
//test4(new Student<Apple>()); //< 出错
stu = new Student<Fruit>();;
//test4(stu); //使用时确定类型
test4(new Student<Object>());
test4(new Student<Fruit>());
}
public static void test(Student<?> stu){
}
public static void test3(Student<Fruit> stu){
}
// <=
public static void test2(Student<? extends Fruit> stu){
}
//>=
public static void test4(Student<? super Fruit> stu){
}
}
没有泛型数组,不能创建泛型数组.
可以只有声明,可以使用?
/**
* 没有泛型数组
* 声明可以使用,但是创建失败
* @author Administrator
*
*/
public class Array {
/**
* @param args
*/
public static void main(String[] args) {
Integer[] arr = new Integer[4];
//Student<String>[] arr2 = new Student<String>[10];//创建失败
Student<?>[] arr2 = new Student[10];
MyArrayList<String> strList =new MyArrayList<String>();
strList.add(0, "a");
String elem =strList.getElem(0);
System.out.println(elem);
}
}
class MyArrayList<E>{
//E[] cap =new E[10]; 没有泛型数组
Object[] cap = new Object[10];
public void add(int idx,E e){
cap[idx] =e;
}
@SuppressWarnings("unchecked")
public E[] getAll(){
return (E[]) cap;
}
@SuppressWarnings("unchecked")
public E getElem(int idx){
return (E) cap[idx];
}
}
/**
* 1.7中使用泛型,声明一次类型即可
* 在使用|创建时不用指定类型
* @author Administrator
*
*/
public class Test7 {
/**
* @param args
*/
public static void main(String[] args) {
List<String> arrList= new ArrayList<String>();
//List<String> arrList2= new ArrayList<>();
}
}
也可查看泛型的其它详解:http://www.cnblogs.com/yinhaiming/articles/1749738.html
/**
* 简化迭代器原理
* hasNext
* next
* @author Administrator
*
*/
public class MyArrayList {
private String[] elem ={"a","b","c","d","e","f","g"};
private int size = elem.length;
private int cursor =-1;
/**
* 判断是否存在下一个元素
* @return
*/
public boolean hasNext(){
return cursor+1<size;
}
/**
* 获取下一个元素
*/
public String next(){
cursor++; //移动一次
return elem[cursor];
}
/**
* 删除元素
*/
public void remove(){
}
/**
* @param args
*/
public static void main(String[] args) {
MyArrayList list = new MyArrayList();
while(list.hasNext()){
System.out.println(list.next());
}
list = new MyArrayList();
while(list.hasNext()){
System.out.println(list.next());
}
}
}
/**
* 简化迭代器原理 加入接口 提供方法
* hasNext
* next
* @author Administrator
*
*/
public class MyArrayList3 implements java.lang.Iterable<String> {
private String[] elem ={"a","b","c","d","e","f","g"};
private int size = elem.length;
/**
* 匿名内部类
* @return
*/
public Iterator<String> iterator(){
return new Iterator<String>(){
private int cursor =-1;
/**
* 判断是否存在下一个元素
* @return
*/
public boolean hasNext(){
return cursor+1<size;
}
/**
* 获取下一个元素
*/
public String next(){
cursor++; //移动一次
return elem[cursor];
}
/**
* 删除元素
*/
public void remove(){
//没有实现
}
};
}
/**
* @param args
*/
public static void main(String[] args) {
MyArrayList3 list = new MyArrayList3();
Iterator<String> it =list.iterator();
while(it.hasNext()){
System.out.println(it.next());
it.remove(); //删除元素
}
it =list.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
System.out.println("增强for,必须实现java.lang.Iterable接口,重写iterator方法");
for(String temp:list){
System.out.println(temp);
}
}
}
增强for循环也是依赖于迭代器实现的,迭代器的效率非常高,有些是直接操作硬盘数据.效率是非常高的./**
* this is a cat and that is a mice and where is the food?
* 统计每个单词出现的次数
*
* 存储到Map中
* key :String
* value:自定义类型
*
* "分拣" 思路
* 1、为所有key创建容器
* 之后容器中存放对应value
* 2、第一次创建容器,并存放值value
* 第二次之后,直接使用容器存放值
* @author Administrator
*
*/
public class Demo01 {
/**
* @param args
*/
public static void main(String[] args) {
String str ="this is a cat and that is a mice and where is the food";
//分割字符串
String[] strArray=str.split(" ");
//存储到Map中
Map<String,Letter> letters = new HashMap<String,Letter>();
for(String temp:strArray){
/*
//1、为所有key创建容器
if(!letters.containsKey(temp)){
Letter col = new Letter();
col.setCount(1); //第一次值存放容器中
letters.put(temp, col);
}else{
//2、 第二次之后,直接使用容器存放值
Letter col =letters.get(temp); //直接使用容器
col.setCount(col.getCount()+1);
}*/
Letter col = null;
if(null==(col=letters.get(temp))){
col = new Letter();
col.setCount(1); //第一次值存放容器中
letters.put(temp, col);
}else{
//2、 第二次之后,直接使用容器存放值
col.setCount(col.getCount()+1);
}
}
//输出Map的值
Set<String> keys = letters.keySet();
for(String key:keys){
Letter col =letters.get(key);
System.out.println("字母:"+key+",次数"+col.getCount());
}
}
public static void test1(){
String str ="this is a cat and that is a mice and where is the food";
//分割字符串
String[] strArray=str.split(" ");
//存储到Map中
Map<String,Letter> letters = new HashMap<String,Letter>();
/*
for(String temp:strArray){
//1、为所有key创建容器
之后容器中存放对应value
if(!letters.containsKey(temp)){
letters.put(temp, new Letter());
}
}
for(String temp:strArray){
// 容器中存放对应value
Letter col =letters.get(temp); //直接使用容器
col.setCount(col.getCount()+1);
}
*/
for(String temp:strArray){
//1、为所有key创建容器
if(!letters.containsKey(temp)){
letters.put(temp, new Letter());
}
//2、 之后容器中存放对应value
Letter col =letters.get(temp); //直接使用容器
col.setCount(col.getCount()+1);
}
//输出Map的值
Set<String> keys = letters.keySet();
for(String key:keys){
Letter col =letters.get(key);
System.out.println("字母:"+key+",次数"+col.getCount());
}
}
}
人生的过程,实际上是一个赌的过程,我们学的时候要学的深入一点,以后会用到的.一定要学的深入.
以后一定要多写代码,多敲代码.加油.