JavaSE基础08-持有对象

容器类

目录

  • 容器类
      • 泛型和类型安全的容器
        • 集合 collection
          • 1.添加一个元素和一组元素
          • 2.容器的打印
          • 3.List
          • 4.迭代器
          • 4.LinkedList
        • 映射 Map

泛型和类型安全的容器

使用普通的容器是不安全的,因为什么都可以放进去,没有限制,拿出来转换也没有限制,所有都需要程序员自己判断;如ArrayList al = new ArrayList();

我们用案例来说明,以下是实验代码

package com.JavaSE06.demo01;

import java.util.ArrayList;

class  Apple{
    private static long counter;
    private final long id=counter++;
    public long id (){
        return id;
    }
}
class Orange{

}
public class AppleAndOrangesWithoutGenerics {
    public static void main(String[] args) {
        //这个普通容器是不安全的
        ArrayList apples = new ArrayList();
        for (int i = 0; i < 3; i++) {
            apples.add(new Apple());
        }
        apples.add(new Orange());
        for (int i = 0; i < apples.size(); i++) {
            //这条语句会报错,因为ArrayList存储了不同类型的对象
            //因为Orange不能转换成Apple
            //因为ArrayList没有限制,什么类型都可以放,所以是不安全的;所有的限制都需要人为的指定
            System.out.println( ((Apple)apples.get(i)).id());
        }
    }
}

以下是使用泛型的容器,是安全的。

package com.JavaSE06.demo01;
import com.JavaSE02.demo02.Array;

import java.util.*;
public class AppleAndOrangleWithGenerics {
    public static void main(String[] args) {
        //使用泛型的安全容器
        //我们使用泛型是为了限制进入容器的对象类型
        ArrayList<String> alstrs = new ArrayList<String>();
        alstrs.add("china");
        alstrs.add("USA");
        for (int i = 0; i < alstrs.size(); i++) {
            System.out.println(alstrs.get(i));
        }
        System.out.println("------------------------------------------");
        ArrayList<Apple> apples = new ArrayList<Apple>();
        for (int i = 0; i < 3; i++) {//普通的打印方式
            //使用了泛型,这个容器只能够放苹果
            apples.add(new Apple());
        }
        for (int i = 0; i < apples.size(); i++) {
            System.out.println(apples.get(i).id());
        }
        System.out.println("************");
        for(Apple c:apples){//这种是针对容器的打印方式
            System.out.println(c.id());
        }
    }
}

同时使用泛型的容器允许我们实现向上转型

package com.JavaSE06.demo01;
import java.util.*;
class GrannySmith extends Apple{ }
class Gala extends Apple{}
class Fuji extends Apple{}
class Bracburn extends Apple{}
public class GenericesAndUpcasting {
    public static void main(String[] args) {
        ArrayList<Apple> apples = new ArrayList<Apple>();
        apples.add(new GrannySmith());
        apples.add(new Gala());
        apples.add(new Bracburn());
        apples.add(new Fuji());
        for (Apple apple : apples) {
            System.out.println(apple.id());
        }
    }
}

###容器类的基本概念
Java容器类的用途是保存对象,并把它划分为两个不同的概念:集合和映射

集合 collection

集合是一个独立元素的序列,这些元素都符合一条或多条规则;
以下是Collection继承图
JavaSE基础08-持有对象_第1张图片

1.添加一个元素和一组元素

ArrayList中的一些常用操作
以下是实验代码

package com.JavaSE06.demo02;

import java.util.*;

public class AddingGroups {
    public static void main(String[] args) {
        //Arrays是集合的一个工具类,提供了很多方法给我们用
        Collection<Integer> c = new ArrayList<Integer>(Arrays.asList(1,2,3,4,5));
        Integer [] moreInts = {6,7,8,9,10};
        //需要先将数组转换成集合对象
        c.addAll(Arrays.asList(moreInts));
        //collections是工具类,提供了很多操作集合的方法
        Collections.addAll(c,11,12,13,14,15);//批量添加  方式1
        Integer [] moreInts2 = {16,17,18,19,20};
        Collections.addAll(c,moreInts);//传数组 批量添加  方式2
        for(Integer i:c) System.out.print(i+",");
        System.out.println();
        List<Integer> list= Arrays.asList(1,2,3,4,5);
        list.set(1,99);//list.set(index,element)   这是list自己的方法,它可以有父类的方法,也有自己的方法
        for (Integer integer : list) {
            System.out.print(integer+",");
        }

    }
}

List中的几种赋值方式

package com.JavaSE06.demo02;
import java.util.*;
class Snow{ }
class Powder extends Snow{ }
class Light extends  Powder{ }
class Heavy extends  Powder{ }
class Crusty extends  Snow{ }
class Slush extends  Snow{ }
public class AsListInference {
    public static void main(String[] args) {
        List<Snow> snowList1=Arrays.asList(new Crusty(),new Slush(),new Powder());
        //ArrayList是List下的一个子类
        List<Snow> snowList2 = new ArrayList<Snow>();
        Collections.addAll(snowList2,new Light(),new Heavy());//使用Collections工具类添加
        List<Snow> snowList3 = new ArrayList<Snow>(snowList1);//初始化时添加
        Snow [] sa =new Snow[snowList2.size()];
        Collections.addAll(snowList3,snowList2.toArray(sa));//使用工具类添加,区别于上面 是先把list转换为数组
        List<Snow> snowList4 = Arrays.<Snow>asList(new Light(),new Heavy());//在初始化时,显式指定类型
        for(Snow s:snowList1) System.out.print(s);
        System.out.println();
        for(Snow s:snowList2) System.out.print(s);
        System.out.println();
        for(Snow s:snowList3) System.out.print(s);
        System.out.println();
        for(Snow s:snowList4) System.out.print(s);
        System.out.println();
    }
}
2.容器的打印

以下是实验代码

package com.JavaSE06.demo02;
import java.util.*;
public class PrintngContainers {
    public static void main(String[] args) {
        System.out.println(fill(new ArrayList<String>()));
        System.out.println(fill(new LinkedList<String>()));
        //set这一分支是不允许重复的,
        System.out.println(fill(new HashSet<String>()));//hash算法底层
        System.out.println(fill(new TreeSet<String>()));//底层是树
        System.out.println(fill(new LinkedHashSet<String>()));//链表和hash算法
        System.out.println("------------------------------------------");
        //map这一分支是键值对对象
        System.out.println(fill(new HashMap<String, String>()));
        System.out.println(fill(new TreeMap<String, String>()));
        System.out.println(fill(new LinkedHashMap<String, String>()));
    }
    static Collection fill(Collection<String> collection){
        collection.add("rat");
        collection.add("cat");
        collection.add("dog");
        collection.add("dog");
        return collection;
    }
    static Map fill(Map<String,String> map){
        map.put("rat","Fuzzy");
        map.put("cat","Rags");
        map.put("dog","Bosco");//这个会被覆盖
        map.put("dog","Spot");
        return map;
    }

}
3.List

List是一个接口底下有两个子类:ArrayList和LinkedList
ArrayList底层是数组,支持随机访问,但增删慢
LinkedList底层是链表,增删快,访问较慢。
如果有频繁的查询操作,则用ArrayList;否则,用LinkedList
以下是实验代码

package com.JavaSE06.demo03List;

import java.util.*;

public class ListFeatures {
    public static void main(String[] args) {
        List<Integer> list =new ArrayList<Integer>();
        list.add(1);
        list.contains(1);//集合从是否包含指定对象
        list.indexOf(1);//查看对象索引
        list.get(1);//得到对象
        list.remove(1);//删除一个对象,当对象不存在时,返回false
        list.add(1,new Integer(2));
        List<Integer> integers = list.subList(0, 2);//截取子list;指出哪里开始哪里结束 list.[fromIndex,toIndex)
        list.containsAll(integers);//判断是否包含此子串,对象本身的比较;即使是打乱顺序,对象(引用)一样的话,返回ture
        Collections.sort(integers);//使用工具类排序
        Collections.shuffle(integers);//打乱顺序,会打乱其引用;如果多个list对象指向同一片空间,那么都会受到影响。


        List<Integer> copy =new ArrayList<Integer>(integers);
        List<Integer> list2 =Arrays.asList(copy.get(0),copy.get(1));//另一种初始化方式
        copy.retainAll(list2);//保留两者都共有的对象
        copy.retainAll(list);//删除子集合
        copy.set(1,2);//将制定index的element重新赋值
        copy.addAll(2,list);//从指定的index开始添加元素,index后的元素往后移动list.length位
        copy.isEmpty();//判断list集合是否为空
        Object[] objects = copy.toArray();//将list集合转为数组

    }
}

4.迭代器

由于容器的种类有很多,而且每种容器的特点都不一样,如ArrayList底层是一个数组,LinkedList底层是链表,很多时候不知道怎么去遍历容器。所以我们需要有一个迭代器去实现对容器的遍历。
迭代器在java中是一个对象,它的工作是遍历容器;
迭代器有两种:Iterator和ListIterator
Iterator只能够单向移动
ListIterator可以双向移动,还可以指定开始遍历的位置;它是Iterator的子类,对基类进行了扩展。

一个简单迭代器的使用案例

public class SimpleIteration {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10,11,12);

        //得到一个普通迭代器,得到数据
        Iterator<Integer> it =list.iterator();
        while(it.hasNext()){
            Integer next = it.next();
            System.out.print(next+" ");
        }
        System.out.println();
        //时候循环得到数据
        for (Integer integer : list) {
            System.out.print(integer+" ");
        }
        System.out.println();
        System.out.println("---------分割线------------------");

    }
}

使用迭代器遍历不同类型的容器

public class CrossContainerInteration {

    public static void display(Iterator<String> it){
        while(it.hasNext()){
            String next = it.next();
            System.out.print(next+" ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        //如果要考虑顺序,就用list底下的容器
        ArrayList<String>  list = new ArrayList<String>(Arrays.asList("cat","dog","pug","yellow dog","big cat"));
        LinkedList<String> link = new LinkedList<String>(list);

        HashSet<String> hs=new HashSet<String>(list);
        TreeSet<String> ts = new TreeSet<String>(list);
        display(list.iterator());
        display(link.iterator());
        //可以看到set容器是无序的。
        //如果只考虑容器速度,可以用set
        display(hs.iterator());
        display(ts.iterator());
    }
}

ListIterator的简单使用案例

package com.JavaSE06.demo04Iterator;

import java.util.*;

public class CrossContainerInteration {

    public static void display(Iterator<String> it){
        while(it.hasNext()){
            String next = it.next();
            System.out.print(next+" ");
        }
        System.out.println();
    }

    public static void main(String[] args) {
        //如果要考虑顺序,就用list底下的容器
        ArrayList<String>  list = new ArrayList<String>(Arrays.asList("cat","dog","pug","yellow dog","big cat"));
        LinkedList<String> link = new LinkedList<String>(list);

        HashSet<String> hs=new HashSet<String>(list);
        TreeSet<String> ts = new TreeSet<String>(list);
        display(list.iterator());
        display(link.iterator());
        //可以看到set容器是无序的。
        //如果只考虑容器速度,可以用set
        display(hs.iterator());
        display(ts.iterator());
    }
}
4.LinkedList

LinkedList 可以被当做栈,队列,双端队列来使用;当有频繁的增删操作时,推荐使用LinkedList。
以下是一些简单的使用方法

package com.JavaSE06.demo05LinkedListAndStack;
import java.util.*;
public class LinkedListFeatures {
    public static void main(String[] args) {
        LinkedList<String> list = new LinkedList<String>(Arrays.asList("dog","cat","big dog","big cat","dragon"));
        System.out.println(list);
        //获取集合第一个元素的三种方式
        System.out.println("list.getfirst: "+list.getFirst());
        System.out.println("list.element()"+list.element());
        System.out.println("list.peek()"+list.peek());
        //删除集合中的元素 三种方式
        System.out.println("list.remove() "+list.remove());
        System.out.println("list.removeFirst() "+list.removeFirst());
        System.out.println("list.poll() "+list.poll());//常用在栈场景中
        System.out.println(list);
        //表头插入
        list.addFirst(new String("Yellow Cat"));
        System.out.println("After addFirst"+list);
        //表尾插入的三种方式
        list.offer("Blue Dog");
        System.out.println("After offer"+list);
        list.add("green Dog");
        System.out.println("After add"+list);
        list.addLast("green Dog");
        System.out.println("After addLast"+list);
        //删除表尾元素 返回被删除的元素
        System.out.println("After removeLast "+list.removeLast());

    }
}

使用LinkedList实现一个简单的Stack

//MyUtil包下自己写的栈
import java.util.LinkedList;
//Stack : First in Last out
public class Stack<T>{
    private LinkedList<T> storage = new LinkedList<T>();
    public void push(T v){storage.addFirst(v);}
    public T peek(){return storage.getFirst();}
    public T pop(){return storage.removeFirst();}
    public boolean empty(){return storage.isEmpty();}
    public String toString(){return storage.toString();}
}


import com.JavaSE06.demo05LinkedListAndStack.MyUtil.Stack;
public class StackTest {
    public static void main(String[] args) {
        Stack<String> stack = new Stack<String>();
        for(String s:"My dog has fleas".split(" ")){
            stack.push(s);
        }
        System.out.println(stack);
        while(!stack.empty()){
            System.out.print(stack.pop()+" " );
        }
    }
}

映射 Map

一组成对的键值对对象,允许使用键来查找值;也被称为关联数组,有时候也被称为字典
Map是没有顺序的。

你可能感兴趣的:(JavaSE)