javaSE第七章——集合

javaSE第七章——集合

泛型

泛型,即"参数化类型"。一提到参数,最熟悉的既是定义方法是有形参,然后调用此方法时传递实参。

参数化类型,就是将类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。

/**
 * @author 辉欲静,而风止。
 * 泛型
 *
 * 1、泛型的类型参数只能是类类型(包括自定义类)
 * 2、泛型的类型参数可以有多个。   如果没有定义具体类型,默认为Object
 */
public class TestGeneral<T> {
    private T p;

    public T getP() {
        return p;
    }

    public void setP(T p) {
        this.p = p;
    }
}

集合的概念

存储一个班的学员信息,假定一个班容纳20名学员。

当我们需要保存一组一样(类型相同)的元素的时候,我们应该使用一个容器来存储,数组就是这样一个容器。

数组有什么缺点?

​ 数组一旦定义,长度将不能再变化。

然而在我们的开发实践中,经常需要保存一些变长的数据集合,于是,我们需要一些能够动态增长长度的容器来保存我们的数据。

而我们保存的数据的逻辑可能是多种多样的,于是就有了各种各样的数据结构。java中对于各种数据结构的实现,既是我们用到的集合。

集合API

集合体系概述

java的集合框架是由很多接口、抽象类、具体类组成的,都位于java.util包中。

在这里插入图片描述

Collection接口

Collection接口–定义了存取一组对象的方法,其子接口Set和List分别定义了存储方式。

​ Set中的数据对象没有顺序且不可以重复。

​ List中的数据对象有顺序且可以重复。

在Collection中定义了一些集合的共有方法:

import java.util.ArrayList;
import java.util.Collection;

/**
 * @author 辉欲静,而风止。
 *集合中的方法
 * 集合中只能存储引用类型
 */
public class CollectionDemo1 {
    public static void main(String[] args) {
        Collection<Integer> c = new ArrayList<>();
                /*
                给集合里添加元素
                */
                int a = 8;
                c.add(1);
                c.add(2);
                c.add(3);
                //如果是基本类型会自动装箱为引用类型
                //(除基本类型之外的所有类型都是引用类型)
                c.add(a);
        /*System.out.println(c);*/
        Collection<Integer> c1 = new ArrayList<>();
                c1.add(5);
                c1.add(6);
                c1.add(7);
                c1.add(8);
                //将指定集合中的元素添加到此集合中 [1, 2, 3, 8, 5, 6, 7, 5]
                c.addAll(c1);
                //保留两个集合中相同的内容 [8, 5, 6, 7, 8]
                c.retainAll(c1);
                //清除集合中的所有元素
                c.clear();
        //        System.out.println(c.isEmpty());//判断集合是否为空
        //System.out.println(c.contains(3));//判断集合中是否包含元素3
       // c.remove(10);//删除元素10
        //如果c和c1里的元素一模一样没有发生改变则返回false,改变返回true
		System.out.println(c.retainAll(c1));//改变返回true,不改返回false
        // c.removeAll(c1);//删除指定集合中包含在该集合中的所有元素c[1, 2, 3] c1[4, 6, 7, 8]
        /*Object[] c2 =c.toArray();//转数组
        System.out.println(c2.length);*/
        Integer[] array = c.toArray(new Integer[c.size()]);//转指定类型的数组
        System.out.println(array.length);//4
                System.out.println(c);
    }
}

List接口及实现类

List继承了Collection接口,有三个实现的类

—ArrayList

​ 数组列表,数据采用数组方式存储。

—LinkedList

​ 链表

—Vector

​ 数组列表,添加同步锁,线程是安全的。

ArrayList实现了长度可变的数组,在内存中分配连续的空间。

遍历元素和随机访问元素的效率比较高

LinkedList采用链表存储方式。插入、删除元素时效率比较高

ArrayList的常用方法
import java.util.ArrayList;

public class ArrayListDemo {
    /*
    list 接口允许元素重复
    list继承了collection
    list是有序的按照插入元素排列,可以存储重复元素,值插入后有索引,可以通过索引访问元素
    ArrayLIst:底层是数组,查询快,从中间删除,添加慢
    Vector:底层是数组,查询快,从中间删除,添加慢,相对于ArrayLIst是线程安全的
    LinkedList:底层是双向链表,查询慢,从中间删除速度快,添加快
     */
    public static void main(String[] args) {
        /*
        add(E e);向列表末尾添加元素,add(int index,E e);向指定位置添加元素
        ArrayList();默认不创建底层数组,当添加第一个元素时,默认创建一个长度为10的数组
        Arraylist(int length)创建对象时,在底层创建一个指定长度的数组,
        ArrayList(Collection collection)把一个实现了collection接口的子类构造成一个ArrayList
        ArrayList是动态数组,当底层数组装满后后自动扩容,扩容为原来的1.5倍

         */
        ArrayList<String> list = new ArrayList<>();
        /*
        add方法底层数组扩容:当底层数组装满后,数组范围会变为原来的1.5倍,扩容的范围不能超过int的范围
        grow();扩容方法
         */
                list.add("a");
                list.add("b");
                list.add("c");
                list.add("a");
                list.add(0,"V");//add(int index,E e)向指定位置添加一个元素,其他元素向后移动
                list.add("d");
                list.add("e");

        System.out.println(list);
        System.out.println(list.get(0));//获取指定位置上的值并返回,查询快
        System.out.println(list.remove(0));//删除指定位置上的元素并返回
        System.out.println(list);

    }
}


import java.util.ArrayList;
import java.util.Comparator;
import java.util.function.Predicate;

/**
 * @author 辉欲静,而风止。
 * ArrayList常用方法
 */
public class ArrayListDemo1 {
    public static void main(String[] args) {
        ArrayList<String> list1 = new ArrayList<>();
                /*
                add方法底层数组扩容:当底层数组装满后,数组范围会变为原来的1.5倍,扩容的范围不能超过int的范围
                grow();扩容方法
                 */
                list1.add("d");
                list1.add("e");
                list1.add("a");
                list1.add("e");
                list1.add(0,"V");//add(int index,E e)向指定位置添加一个元素,其他元素向后移动
                list1.add("c");
                list1.add("b");
                //条件删除
            list1.removeIf(new Predicate<String>() {//条件删除  删除满足给定谓词的此集合的所有元素
                @Override
                public boolean test(String s) {
                    return s.equals("e");
                }
            });
             System.out.println(list1);
             //排序  匿名内部类
             list1.sort(new Comparator<String>() {
                 @Override
                 public int compare(String o1, String o2) {
                     return o1.compareTo(o2);
                 }
             });
        System.out.println(list1);
    }
}

import java.util.ArrayList;

public class ArrayListDemo2 extends ArrayList {
    public static void main(String[] args) {
        ArrayListDemo2 list =new ArrayListDemo2();
                list.add("a");//0
                list.add("b");
                list.add("c");
                list.add("d");//3
                list.add("e");
        System.out.println(list);
       /* list.removeRange(0,3);//removeRange只能在ArrayList子类中使用,删除一个左闭右开的区间元素
        System.out.println(list);*/
                list.set(3,"zwj");//替换指定位置的元素
        System.out.println(list);

    }
}
LinkedList的常用方法

add(int index,Object element) 向指定位置添加指定类型的元素

addFirist(Object element) 向队首添加元素

addLast(Object element) 向队尾添加元素

get(int index) 获取指定位置元素

removeFirst() 移出队首元素

removeLast() 移出队尾元素

remove(int index) 移出指定位置元素

getFirst() 获取队首元素

getLast() 获取队尾元素

import java.util.LinkedList;

public class LinkedListDemo {
	
	public static void main(String[] args) {
		LinkedList<String> list = new LinkedList<>();
		                    list.add("a");
		                    list.add("b");
		                    list.add("c");
		                    list.add("d");
		                    list.add("e");
		                  
		                   // list.remove(2);
		                    
                    /*  Node<E> node(int index) {
						        // assert isElementIndex(index);
						        if (index < (size >> 1)) {
						            Node<E> x = first;
						            for (int i = 0; i < index; i++)
						                x = x.next;
						            return x;
						        } else {
						            Node<E> x = last;
						            for (int i = size - 1; i > index; i--)
						                x = x.prev;
						            return x;
						        }
						    }
						    
						传入一个索引,如果索引小于集合一半,从头结点开始查找,直到找到这个位置的值    
						                       如果大于一半,从尾结点开始查找,直到找到这个位置的值    
                     */
                    System.out.println(list.get(2));
		            System.out.println(list);
	}

}

List接口集合迭代

for循环遍历
 public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
         list.add(1);
         list.add(5);
         list.add(2);
         list.add(4);
         list.add(3);
      /*//for循环  循环时允许删除元素但需要注意索引与集合长度之间的关系
        for (int i = 0; i < list.size(); i++) {
            if(list.get(i)==2){
                list.remove(i);//删除索引为i的元素
            }
            System.out.println(list.get(i));
            //System.out.println(list.get(i));
        }
        System.out.println(list);*/
 }
增强for循环的遍历
	/*//增强for循环   不允许从中删除元素
        for(Integer item:list){
            if(item==3){
                list.remove(item);
            }
            System.out.println(item);

        }*/
迭代器遍历
		//迭代器遍历
        Iterator<Integer> it = list.iterator();
           while (it.hasNext()){
               //System.out.println(it.next());//遍历列表
               Integer item = it.next();
               if(item==1){
                   it.remove();//删除列表中指定的元素
               }
               System.out.println(item);
           }
        System.out.println(list);
stream流遍历
import java.util.ArrayList;
import java.util.stream.Stream;

/**
 * @author 辉欲静,而风止。
 * stream流遍历
 */
public class StreamDemo {
    public static void main(String[] args) {
        ArrayList<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        Stream<Integer> s = list.stream();
        /*s.forEach(new Consumer<Integer>() {//Stream流遍历
            @Override
            public void accept(Integer integer) {
                System.out.println(integer);
            }
        });
        */
        s.forEach(integer -> System.out.println(integer));
    }
}

Set接口

● Set接口继承了Collection接口。

​ Set中所存储的元素是不重复的,但是是无序的, Set中的元素是没有索引的

● Set接口有两个实现类

​ ● HashSet

​ HashSet类中的元素不能重复,即彼此调用equals方法比较,都返回false。

​ 底层数据结构是哈希表+链表

​ 哈希表依赖于哈希值存储

​ ● TreeSet

​ 可以给Set集合中的元素进行指定方式的排序。存储的对象必须实现Comparable接口。

​ TreeSet底层数据结构是二叉树(红黑树是一种自平衡的二叉树)

Set接口集合迭代

● 三种遍历方式

​ 增强for循环

​ 迭代器遍历

​ 流遍历

import java.util.HashSet;

public class HashSetDemo {
    /*
    set接口:键不可以重复,值没有索引
    Hashset:无序,底层使用哈希表+链表+红黑树
    TreeSet:有序(按照值(编码)的顺序排序)底层是红黑树
     */
    public static void main(String[] args) {
        HashSet<Integer> set = new HashSet<>();
        set.add(2);
        set.add(21);
        set.add(12);
        set.add(24);
        set.add(2);
        System.out.println(set);//[2, 21, 24, 12]
        /*
        hashset添加时如何判断值是否重复
        添加时会调用hashcode(),equals()方法
        添加时要比较内容是否相等,既要保证效率又要保证安全
         */
        int h = "ssssssssss".hashCode();//先调用hashcode()计算出一个哈希值,比较哈希值,非常快但不安全
        int h1 = "sssssssssss00000".hashCode();
        System.out.println(h==h1);//false

        int s = "通话".hashCode();
        int s1 = "重地".hashCode();
        System.out.println(s==s1);//true
        //当哈希值相同时,再调用equals()方法比较


    }
}

Map接口

Map接口概述

​ 将键映射到值的对象

​ 一个映射不能包含重复的键

​ 每个键最多只能映射到一个值

Map接口的常用方法
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/*
   Map集合
       双列存储  key(键不能重复)  value(可以重复)
       clear() 清除列表中所有元素
       remove(Object key)   移出指定键所对应的元素
       replace(K key, V value)   替换已有键的值  如果键不存在,则不能替换
       put(key,value)  添加键值对
       putAll(Map<? extends K,? extends V> m) 
       containsKey(Object key)  判断是否包含指定的键
       containsValue(Object value)  判断是否包含指定的值
       get(Object key)   获取指定键所对应的值(根据键查找值,如果键不存在,则返回null)
       values()  返回集合所有的值
       size() 获取集合长度
       isEmpty()  判断集合是否为空
       
       keySet() 
       entrySet() 
       forEach(BiConsumer<? super K,? super V> action) 
       
     HashMap
     TreeMap
     Hashtable(线程安全)
                
 */
public class HashMapDemo1 {
	
	 public static void main(String[] args) {
		Map<String,String> map = new HashMap<>();
		                   map.put("a", "a");
		                   map.put("a", "b");
		                   map.put("b", "b");
		                   map.put("w", "c");
		                   map.put("s", "c");
		                   map.put(null, "c");
		                   //map.clear();
		                   //map.remove("b");
		                   //map.replace("b","bbbb"); //替换已有键的值  如果键不存在,不能替换
		                   System.out.println(map.isEmpty());
		                   System.out.println(map.containsKey("a"));
		                   System.out.println(map.containsValue("c"));
		                   System.out.println(map.size());
		              Collection<String> s = map.values();//返回所有的值
		              System.out.println(s);
		              System.out.println(map.get("ss"));//根据键查找值,键不存在返回null
		        	  System.out.println(map);
		        
		        
	}

}

可看到键重复后值被替换,HashMap无序,TreeMap按照键排序,LinkedHashMap和添加顺序一致

HashMap

​ HashMap中元素的key值不能重复, 排列顺序是不固定的,可以存储一个为null的键。

 public static void main(String[] args) {
		Map<String,String> map = new HashMap<>();
		                   map.put("a", "w");
		                   map.put("z","q");
		                   map.put("a", "b");
		                   map.put("b", "b");
		                   map.put("w", "c");
		                   map.put("s", "c");
							map.put(null,"o");
		 					System.out.println(map);
 }

运行结果:

{null=o, a=b, b=b, s=c, w=c, z=q}

● TreeMap

​ TreeMap中所有的元素都保持着某种固定的顺序,如果需要得到一个有序的Map就应该

​ 使用TreeMap,key值所在类必须实现Comparable接口。

import java.util.TreeMap;

public class TreeMapDemo {
	
	 public static void main(String[] args) {
		
		 /*
		   按照键的顺序排序,用哪个类型的类作为键,那么必须实现Comparable
		  */
		 TreeMap<String, String> tmap = new TreeMap<>();
		                         tmap.put("b","z");
		                         tmap.put("a","a");
		                         tmap.put("d","d");
		                         tmap.put("c","w");
		                         tmap.put("c","z");
		                     
		                         System.out.println(tmap);
		                        
	}

● HashTable

​ 实现了同步。

​ 不能存储为null的键

import java.util.Hashtable;

public class HashTableDemo {
	
	 public static void main(String[] args) {
		 /*
		   底层也是哈希表+链表(红黑树)实现
		      是线程安全  synchronized    Stringbuffer,Vector  
		   
		  */
		 Hashtable<String,String> hmap = new Hashtable<>();
		                   hmap.put("a","a");
		                   hmap.put(null,"a");
	 }

}

运行结果:

Exception in thread "main" java.lang.NullPointerException
	at java.util.Hashtable.put(Hashtable.java:465)
	at com.ff.javaCollection1.map.HashTableDemo.main(HashTableDemo.java:15)

Map集合遍历

方式1:根据键找值

• 获取所有键的集合

• 遍历键的集合,获取到每一个键

• 根据键找值

方式2:根据键值对对象找键和值

• 获取所有键值对对象的集合

• 遍历键值对对象的集合,获取到每一个键值对对象

• 根据键值对对象找键和值

import java.util.HashMap;
import java.util.Map.Entry;
import java.util.function.BiConsumer;
import java.util.Set;


/**
 * @author 辉欲静,而风止。
 * map 集合的遍历
 */
public class HashMapDemo2 {
	/*
   Map集合

     HashMap
             底层存储结构
                      哈希表+链表/红黑树
     put方法实现
       public V put(K key, V value) {
        return putVal(hash(key), key, value, false, true);
     }

 */

	 public static void main(String[] args) {
		 HashMap<String,String> map = new HashMap<>();
		                   map.put("a", "a");
		                   map.put("a", "b");
		                   map.put("b", "b");
		                   map.put("w", "c");
		                   map.put("s", "c");
             //Map遍历方式1:keySet() 
	       /* Set<String>  keyset = map.keySet();//返回map中所有键  封装到一个Set集合中
	               for(String key : keyset){
	            	   System.out.println(key+"::"+map.get(key));
	               }  */  
		                   
		   //方式2      entrySet()将map中底层存储键值的Entry对象,封装到一个Set集合中
		   /* Set<Entry<String, String>> entrySet =    map.entrySet();
		        for(Entry<String, String> entry : entrySet){
		        	   System.out.println(entry.getKey()+"::"+entry.getValue());
		        }*/
		  
		    //方式3
		   map.forEach(new BiConsumer<String, String>() {
			   @Override
				public void accept(String k, String v) {
					 System.out.println(k+":::"+v);
				}
			});
	}

}

Collections类

Collections是集合类的工具类,与数组的工具类Arrays类似

addAl l(Col lection<? super T> c, T… elements);

binarySearch(List<? extends Comparable<? super T>> l ist, T key)

sort(List l ist)

sort(List l ist, Comparator<? super T> c)

swap(List<?> l ist, int i, int j)

copy(List<? super T> dest, List<? extends T> src) ; 注意 dest size需大于等于src.size

emptyList() 返回为空的集合,不能添加数据

fi l l(List<? super T> l ist, T obj)

max(Col lection<? extends T> col l)

min(Col lection<? extends T> col l)

replaceAl l(List l ist, T oldVal, T newVal)

reverse(List<?> l ist)
@Override
public void accept(String k, String v) {
System.out.println(k+":::"+v);
}
});
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值