天天看点

黑马程序员——Java基础---集合                                       集合

              -----------android培训、java培训、java学习型技术博客、期待与您交流!------------ 

                                       集合

一、基本数据类型包装类

基本数据类型 引用数据类型:即对象
int Integer
long Long
short short
boolean Boolean
char Character
float Float
double Double

以Integer为例: 常量:static 最大值MAX_VALUE、最小值MIN_VALUE

2、基本数据类型包装类的最常见作用: 用于基本数据类型和字符串类型之间做转换。 1)基本数据类型转成字符串: 基本数据类型+""; 基本数据类型.toString(基本数据类型值): 如:Integer.toString(34);//把int类型的34变成字符串"34" 2)字符串转成基本数据类型: static xxx a=Xxx.parseXxx(String str)                (静态调用方式) 例如:int a=Integer.parseInt("123");//必须传入数字格式的字符串 double d=Double.parseDouble("12.32"); boolean b=Boolean.parseBoolean("true"); 可以按进制进行转换: Integer.parseInt("110",2) 注意:一个非静态的方法:字符串转基本数据类型 Integer  i=new Integer("123");//先封装成对象(对象调用方式) int  num= i.intValue(); 3)进制转换: a)10进制转换成其他进制 toBinaryString(): toHexString(); toOctalString() b)其他进制转换成10进制 Integer.parseInt("110",2) Integer.parseInt("3c",16) 示例:

<span style="font-size:14px;">//引用数据类型
public class IntegerDemo {

    public static void main(String[] args) {
          //整形类型的最大值
          sop("int max="+Integer. MAX_VALUE);
          //将一个基本数据类型转成字符串
          sop(Double.toString (12));
         
          //将一个字符串转换成整数
          sop("num="+(Integer. parseInt("12")+4));
         
          //进制
          sop(" 6="+Integer. toBinaryString(6));
          sop("-6="+Integer. toBinaryString(-6));
          sop("60="+Integer. toHexString(60));//16进制
          //其他进制转换成10进制
          sop("num="+Integer. parseInt("110",2)); //按照指定的进制进制转换
          sop("3c="+Integer. parseInt("3c",16));

    }
    public static void sop(String str){
         System. out.println(str);
    }
}</span>
           

二、基本数据类型包装类的新特性: 1、Integer x=new Integer(4);   Integer x=4; //新特性:自动装箱,4就变成对象==new Integer(4);其隐式的完成。           //为了简化书写 2、新特性的时候,健壮性要差一点;要进行是否为空(null)的判断; 3、Integer m=128;   Integer n=128;   sop("m==n:"+(m==n)); //false            Integer a=127;  Integer b=127;  sop("a==b:"+(a==b)); //true:因为a和b指向了同一个Integer对象 //因为,当数值在byte范围内时,对于新特性,如果该数值已经存在,不会开辟新的空间; 示例:

<span style="font-size:14px;">//JDK1.5版本的新特性
public class IntegerDemo2 {

    public static void main(String[] args) {
          //Integer x=new Integer(4);
         Integer x=4; //新特性:自动装箱  4就变成对象了===new Integer(4);其隐式的完成
          //为了简化书写
         x=x+2; //x+2:中的x进行了自动拆箱:x.intValue(),变成 int类型的,再和2进行加减运算;
               //在将和进行装箱付给x
         
         Integer m=128;
         Integer n=128;
          sop("m==n:"+(m==n)); //false
         
         Integer a=127;
         Integer b=127;
          sop("a==b:"+(a==b)); //true:因为a和b指向了同一个Integer对象
                       //因为,当数值在byte范围内时,对于新特性,如果该数值已经存在,不会开辟新的空间;
    }
    public static void method(){
         Integer x= new Integer("123" );
         Integer y= new Integer(123);
          sop("x==y :"+(x==y)); //false 两个不同的对象
          sop("x.equals(y) :"+x.equals(y)); //true  Integer复写了Object的equals方法,用于比较数值
    }
    public static void sop(String str){
         System. out.println(str);
    }
}
</span>
           

                                                                            集合 一、体系概述 1、为什么出现集合类? 数据多了需要存储:-->对象;对象多了,也需要存储--->数组或者集合; 即对象多了用集合存,数据多了用对象存; 2、数组和集合都是容器,有何不同?为什么有了数组还要集合? 1)数组虽然也可以存储对象,但长度是固定的;集合长度是可变的; 2)数组中可以存储基本数据类型,集合只能存储对象。 ************数组一定义的时候,已经指定了类型,因此,只能存同一种类型的对象。 ************而集合是,只要是对象就可以存储。 集合的应用更广泛; 3、集合的特点: 集合只能用于存储对象;集合长度可变;集合可以存储不同类型的对象。

4、集合框架:不断向上抽取出来的:Collection 参阅顶层,创建底层;

黑马程序员——Java基础---集合                                       集合

List{ ArrayList、LinkedList、Vector Collection{ set{  TreeSet、HashSet 5、为什么会出现这么多的容器? 因此每一个容器对数据的存储方式都不同; 这个存储方式我们称之为:数据结构; 二、共性方法

黑马程序员——Java基础---集合                                       集合

注意:对象和集合一样都是存放的地址值 1)add( )方法的参数类型是Object,以便于接收任意类型的对象。 2)集合中存储的都是对象的引用(地址)

3、取两个集合元素的交集  getRetainAll( ) 注意:如果没有交集   就为空,什么也不存 removeAll( ):去掉相同 的元素 示例:

<span style="font-size:14px;">import java.util.*;
//集合
public class CollectionDemo {

    public static void main(String[] args) {
          method_2();  
    }
    public static void method_2(){       
          ArrayList al1=new ArrayList();
          al1.add("aaa");
          al1.add("bbb");
          al1.add("ccc");
          al1.add("ddd");
         
          ArrayList al2=new ArrayList();
          al2.add("aaa");
          al2.add("bbb");
          al2.add("eee");
          al2.add("fff");
          sop("al1="+al1);
          //取交集
          al1.retainAll(al2);//al1中只保留与al2中相同的元素
          sop("al1取al2的交集="+al1);
          sop("al2="+al2);
          al2.removeAll(al1);
          sop("al2去掉al1相同的元素="+al2);
    }
    public static void baseMethod(){
          //创建一个集合容器,使用Collection接口的子类,ArrayList
                  ArrayList al=new ArrayList();
                  //1、添加元素
                  al.add("aaa");
                  al.add("bbb");
                  al.add("ccc");
                  al.add("ddd");
                  //2、获取个数,即集合的长度
                  sop("al="+al);
                  sop("al.size="+al.size());
                  //3、删除
                  sop(al.remove("bbb"));
                  sop("al-"+al);
//               al.clear();//清空集合元素
//                sop(al );
                  //4、判断
                  sop("al是否包含bbb:"+al.contains( "ccc"));
                  sop("al是否为空:"+al.isEmpty());
    }
    public static void sop(Object obj){
         System. out.println(obj);
    }
}</span>
           

三、迭代器: 1、 Iterator  it=al.interator();//对象al调用方法,返回的是Iterator接口 这个方法返回的是这个接口的子类对象;该子类对象怎么建立被封装起来了。

接口型引用只能指向自己的子类对象,该对象是通过方法.interator()获取的。 Iterator接口中有:next( ); hasNext( );remove( );方法 其中:next():返回迭代的下一个元素 2、什么是迭代器? 其实就是集合取出元素的方式: 3、集合的特点: 把取出方式定义在集合的内部,这样取出方式就可以直接访问集合内部的元素。那么取出方式就被定义成内部类。

而每一个容器的数据结构不同,所以取出的动作细节也不一样。但是都有共性的内容:判断和去除。 那么,可以将共性内容进行抽取。

内部类实现接口的方式:

黑马程序员——Java基础---集合                                       集合

那么,这些内部类都符合一个规则,该规则就是Iterator接口。如何获取集合的取出对象呢? 通过一个对外提供的方法,iterator( ).

黑马程序员——Java基础---集合                                       集合

4、对于取出这个动作不足以用一个函数来描述,它需要用多个功能来体现;当多个功能体现的时候,把多个功能封装到一个对象当中去。 每个容器中都有一个取出对象,因为数据结构不同,每个取出动作中取出的实现方式都不一样。 这个取出需要被描述一下,那么是怎么样描述的? 通过一个类来完成,而这个类就定义在了集合内部。取出这个类定义在集合内部,这是为什么呢? 因为元素在集合中,你想直接操作元素,定义内部类最方便。这个内部类完成取出动作是定义。 例子:娃娃机: 其中:机箱是 容器,夹子是迭代器(取出方式),该夹子定义在了箱子中。 示例:

<span style="font-size:14px;">//获取元素并操作元素
import java.util.*;
public class InteratorDemo {
    public static void main(String[] args) {
          ArrayList al=new ArrayList();
          al.add("java01");
          al.add("java02");
          al.add("java03");
          al.add("java04");
         
//       Iterator it=al.iterator();//获取迭代器,用于取出集合中的元素
//       while(it.hasNext()){
//            sop(""+it.next());
//       }   
          //啊使用for循环节省内存空间
          for(Iterator it=al.iterator();it.hasNext();)
              sop(""+it.next());
    }
    public static void sop(String str){
         System. out.println(str);
    }
}</span>
           

三、List集合共性方法 1、Collection: 1)List:   元素是有序的,元素可以重复,因为该集合体系是有索引的。 a) ArrayList:底层使用的是数组结构:特点:(因为有角标)查询速度快,增删较慢。线程不同步(JDK1.2) b) LinkedList:底层使用的是链表结构:特点:增删快,查询慢。线程同步,速度慢,被ArrayLsit取代 了。 c)  Vector:底层是数组数据结构:(JDK1.0) Vector出现的时候,集合框架还不存在。 ArrayList和Vector的区别:ArrayList是不同步的;而Vector是同步的。 **************数组长度是固定的,可变长度的数组: ArrayList默认的长度是10,如果超过长度,就会new 一个新的数组,以50%递增,然后把其原数组装进去。 而,Vector是100%延长,因此ArrayList好一些,既可以延长,有可以节约空间。 2)Set:   元素是无序的,元素不可以重复 2、List集合中特有方法:凡是可以操作角标的方法都是该体系的特有方法。 1)增: 在指定位置插入元素:add(int index,element) addAll( int index ,Collection) 2)删: remove(index): 3)改: set(index,element) 4)查: get(index): subList(from,to):包含头,不包含尾 listIterator( 0) 示例: package jihe; //list import java.util.*; //以ArrayList为例 public class ListDemo {

    public static void main(String[] args) {           method_1();     }     public static void sop(String str){          System. out.println(str);     }     //增     public static void method_1(){                     ArrayList al=new ArrayList();           //添加元素           al.add("java01");           al.add("java02");           al.add("java03");           sop("原元素="+al);                     ArrayList a2=new ArrayList();           //添加元素           a2.add("hello");           a2.add("world");            sop("a2="+a2);                     //在指定位置添加元素           al.add(0, "aaa");           al.add(1,"bbb");           sop("al="+al);           al.addAll(3,a2);           sop("添加a2后="+al);           //删除指定位置的元素          al.remove(2);           sop("删除后="+al);                     //3、修改元素           al.set(0,"jiahao");           sop("改变后al="+al);           //通过角标获取元素           sop("al[0]="+al.get(0));                     sop("子List="+al.subList(0,3));                     for(ListIterator li=al.listIterator();li.hasNext();){               sop(""+li.next());          }        } } 注意:可以通过集合操作元素,也可以通过迭代器操作;那么,就有两种方式操作操作元素。 对元素的并发访问,容易产生安全隐患。 3、ConcurretModificationException  extends RunntimeException:当方法检测到对象的并发修改,但不允许这种修改时,抛出异常。 4、Iterator it=al.iterator();迭代器只能进行:hasNext ();next();和remove操作。其他 的不行。怎么办? 其子类ListIterator  因为有指针、角标,因此方法比其父多好多。 5、List集合特有迭代器ListIterator,是Iterator 的子类。 在迭代时,不可以通过集合对象的方法操作集合中的元素。因为会发生ConcurrentModificationException异常; 所以,在迭代时,只能通过迭代器的方法操作元素。可是呢Iterator是有限的,只能对元素进行判断、取出、删除操作。如果想要使用其他的操作,比如:添加、修改等,就要使用其子接口LstIterator,该接口只能通过List集合的listIterator()方法获取。 6、li.hasNext():迭代后有没元素:   li.hasPrevious()::迭代后有没有元素 7、vector 枚举是Vector特有的取出方式: 其实:枚举和迭代是一样的;因为枚举的名称和方法的名称都过长,所以被迭代器取代了。 示例:

<span style="font-size:14px;">package jihe;
//演示Vector集合
import java.util.*;
public class VectorDemo {

    public static void main(String[] args) {
          method();

    }
    public static void sop(String str){
         System. out.println(str);
    }
    public static void method(){
          Vector v=new Vector();
          v.add("java01");
          v.add("java02");
          v.add("java03");
          sop("v原集合:"+v);
         
          Vector v2=new Vector();
          v2.add("hello");
          v2.add("world");
          sop("v2原集合:"+v2);
          //增
          v.add(2, "jiahao");
          v.addAll(v2);
          sop("v="+v);
          v.addAll(0, v2);
          sop("v="+v);
          //删
         v.remove(0);
          sop("删除v[0]:"+v);
          v.removeAll(v2);
          sop("删除v2="+v);
          //改
          v.set(0, "quan");
          sop("改后="+v);
          //获取
          sop("get[0]="+v.get(0));
          //  
          Enumeration en=v.elements();
          while(en.hasMoreElements()){
              sop(""+en.nextElement());
         }
    }   
}</span>
           

8、LinkedList 特有方法: 1)addFirst()/addLast() 2)getFirst()/getLast():获取元素,但是不删除元素 如果元素集合为空,则抛出NoSuchElementException异常 3)removeFirst()/removeLast():获取元素,并删除元素 如果元素集合为空,则抛出NoSuchElementException异常 -----》新方法(JDK1.6)取代方法: offerFirst()/offerLast():添加元素 peekFirst()/peekLast();获取但是不删除元素,如果列表为空,则返回null,而不抛出异常。 pollFirst()/pollLast(): 获取并移除列表的元素,如果列表为空,则返回null,而不抛出异常。 示例: 9、LinkedList练习: 练习一:使用LinkedList模拟一个堆栈或者队列数据结构; 堆栈:先进后出; 队列:先进先出 封装,基于以前存在的结构功能,封装成我们需要的结构。

示例:

<span style="font-size:14px;">package jihe;
//使用LinkedList模拟堆栈
import java.util.*;
public class DuizhanDemo {

    public static void main(String[] args) {
         DuiLie dui= new DuiLie();
         dui.myAdd( "java01");
         dui.myAdd( "java02");
         dui.myAdd( "java03");
          while(!dui.isNull()){
             System. out.println(dui.myGet());
         }
    }
}
class DuiLie{
    private LinkedList link ;
    DuiLie(){
          link= new LinkedList();
    }
    public void myAdd(Object obj){
          link.addFirst(obj);//link.addLast(obj);
    }
    public Object myGet(){
          return link .removeLast();//堆栈:removeFirst();
    }
    public boolean isNull(){
          return link .isEmpty();
    }
}</span>
           

  练习二:去除ArrayList中重复的元素:

<span style="font-size:14px;">package jihe;
//去除ArrayList中重复的元素
import java.util.*;
public class LinkedListDemo3 {

    public static void main(String[] args) {
          ArrayList al=new ArrayList();
          al.add("java01");
          al.add("java02");
          al.add("java01");
          al.add("java03");
          sop("原al="+al);
         al= singelElement(al);
          sop("al="+al);

    }
    public static void sop(Object obj){
         System. out.println(obj);
    }
    public static ArrayList singelElement( 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;
    }
}</span>
           

注意:   练习三:将自定义对象作为元素存到ArrayList( )集合中,并去除重复元素: 比如:存人对象,同姓名同年龄,视为同一个人,为吃饭元素: 思路: 1)对人进行描述,把数据封装成人对象。 2)定义容器,将人存入。 3)取出。 注意:List集合判断元素是否相等,依据的是元素的equals方法。 ArrayList知不知道判断相同的条件?ArrayList判断的是对象是否相同,判断对象是否相同使用equals()方法,在使用对象的equals()方法和另一个对象比较。比较的是地址值。 remove底层也调用了equals方法; 因此:ArrayList LinkedList的remove contains方法依赖的都是equals方法。

一、hashSet Set:元素是无序的(存入和取出的顺序不一致),元素不可以重复。 |-----HashSet:底层数据结构是hash表。 HashSet:如何保证元素的唯一性? 是通过元素的两个方法,hashCode和equals方法。 如果元素的HashCode值相同,才会判断equals是否为true. 如果元素的HashCode值不相同,不会调用equals方法。

|-----TreeSet: **********Set集合的功能和Collection是一致的。 1、HashSet:底层数据结构是hash表,表里面存入数据的顺序是按照hash值的大小存的,而不是按照存入的顺序。 2、 在hash表中,当hash值重复的时候,比较两个元素对象是否相同。如果相同,认为是同一个对象,haash表中元素不重复,因此添加失败。 如果对象不相同,就在同一个地址值下顺延存放。(hash表中,完全以hash值为主。) 示例:

<span style="font-size:14px;">import java.util.*;
public class HashSetDemo {

    public static void main(String[] args) {
          hashSet();

    }
    public static void sop(Object obj){
         System. out.println(obj);
    }
    public static void hashSet(){
          HashSet hs=new HashSet();
          hs.add("java01");
          hs.add("java02");
          hs.add("java03");
          sop(hs.add( "java02"));//false:地址值和对象都一样,添加不成功
         
          Iterator it=hs.iterator();
          while(it.hasNext()){//是无序的
              sop(""+it.next());
         }
    }

}</span>
           

3、存储自定义对象 ******四个对象,在hash表里有四个位置的存储,已经存进去了,就不会判断equals() 4、覆盖Person的hashCode方法,就建立Person对象自己的hash值,那么怎么建立hash值? 你的判断条件是什么,那么,我就依据 条件建立hash值。 5、我们在自定义对象的时候,通常要复写hashCode(),equals()方法。 示例:

<span style="font-size:14px;">package jihe;
import java.util.*;
/*
 * 往HashSet中存入自定义对象
 * 姓名、年龄相同视为同一个人,重复元素
 */
public class HashSetDemo {

    public static void main(String[] args) {
          //hashSet();
          HashSet hs=new HashSet();
          hs.add(new Personn("a1",32)) ;
          hs.add(new Personn("a3",34)) ;
          hs.add(new Personn("a4",22)) ;
          hs.add(new Personn("a3",34)) ;
         
          Iterator it=hs.iterator();
          while(it.hasNext()){
             Personn p=(Personn)it.next();
              sop(p.getName()+"...."+p.getAge());
         }

    }
    public static void sop(Object obj){
         System. out.println(obj);
    }
    /*public static void hashSet(){
         HashSet hs=new HashSet();
         hs.add("java01");
         hs.add("java02");
         hs.add("java03");
          sop(hs.add("java02"));//false:地址值和对象都一样,添加不成功
         
         Iterator it=hs.iterator();
         while(it.hasNext()){//是无序的
              sop(""+it.next());
         }
    }*/

}
class Personn{
    private String name;
    private int age ;
    Personn(String name, int age){
          this.name =name;
          this.age =age;
    }
    public int hashCode(){
        System. out.println(this .name +"...hashCode" );
          return name .hashCode()+age*39;//尽量保证hash值的唯一性
    }
    public boolean equals(Object obj){
          if(!(obj instanceof Personn))
              return false ;
         Personn p=(Personn)obj;
        System. out.println(this .name +"..equals.." +p.name );//相互比较
         
          return this.name .equals(p.name)&& this.age ==p.age ;//其中的equals()是字符串的方法
    }
    public String getName(){
          return name ;
    }
    public int getAge(){
          return age ;
    }   
}</span>
           

6、hashSet判断和删除的依据 注意:对于判断元素是否存在,以及删除等条件,依赖的方法是元素的hashCode值和equals方法。

ArrayList判断、删除元素只依赖equals,而HashSet依赖hashCode和equals方法

数据结构不同,判断的条件也不同。

示例:

<span style="font-size:14px;">package jihe;
import java.util.*;
/*
 * 往HashSet中存入自定义对象
 * 姓名、年龄相同视为同一个人,重复元素
 */
public class HashSetDemo {

    public static void main(String[] args) {
          //hashSet();
          HashSet hs=new HashSet();
          hs.add(new Personn("a1",32)) ;
          hs.add(new Personn("a2",34)) ;
          hs.add(new Personn("a3",21)) ;
          //hs.add(new Personn ("a2",34));
         
          //
          sop("a2:"+hs.contains( new Personn("a2",34)));//先比较hashCode值,再比较equals
         hs.remove( new Personn("a3" ,21));       
         
          Iterator it=hs.iterator ();
          while(it.hasNext()){
             Personn p=(Personn)it.next();
              sop(p.getName()+"...."+p.getAge());
         }

    }
    public static void sop(Object obj){
         System. out.println(obj);
    }
    /*public static void hashSet(){
         HashSet hs=new HashSet();
         hs.add("java01");
         hs.add("java02");
         hs.add("java03");
          sop(hs.add("java02"));//false:地址值和对象都一样,添加不成功
         
         Iterator it=hs.iterator();
         while(it.hasNext()){//是无序的
              sop(""+it.next());
         }
    }*/

}
class Personn{
    private String name;
    private int age ;
    Personn(String name, int age){
          this.name =name;
          this.age =age;
    }
    public int hashCode(){
        System. out.println(this .name +"...hashCode" );
          return name .hashCode()+age*39;//尽量保证hash值的唯一性
    }
    public boolean equals(Object obj){
          if(!(obj instanceof Personn))
              return false ;
         Personn p=(Personn)obj;
        System. out.println(this .name +"..equals.." +p.name );//相互比较
         
          return this.name .equals(p.name)&& this.age ==p.age ;//其中的equals()是字符串的方法
    }
    public String getName(){
          return name ;
    }
    public int getAge(){
          return age ;
    }
    
}</span>
           

版权声明:本文为CSDN博主「lanzhenyue1990」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.csdn.net/lanzhenyue1990/article/details/49806043