Java技术

一.java集合

1.Java集合分为Collection和Map

2.Collection分为:List(Vector ArrayList LinkedList)、Set(HashSet LinkedSet TreeSet)

AarrayList

package collection;

import java.util.ArrayList;

public class Collection {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        //add:添加单个元素
        arrayList.add("jack");
        arrayList.add(10);
        arrayList.add(true);
        System.out.println("arrayList="+arrayList);
        //remove删除元素
       // arrayList.remove(0);//删除第一个元素
        arrayList.remove("jack");//指定删除某个对象
        System.out.println("arrayList="+arrayList);
        //contains:查找元素是否存在
        System.out.println(arrayList.contains("jack"));//false,因为删除了元素jack
        //获取元素个数
        System.out.println(arrayList.size());//2
        //isEmpty:判断是否为空
        System.out.println(arrayList.isEmpty());//false
        //clear:清空
       arrayList.clear();
        System.out.println(arrayList);//[]
        //addAll:添加多个元素
        ArrayList arrayList2 =new ArrayList();
        arrayList2.add("p");
        arrayList2.add("l");
        arrayList2.add("y");
        arrayList.addAll(arrayList2);
        System.out.println(arrayList);//[p, l, y]
        //containsAll:查找多个元素
        System.out.println(arrayList.containsAll(arrayList2));//true
        //removeAll:删除多个元素
        arrayList.add(19);
        arrayList.removeAll(arrayList2);
        System.out.println(arrayList);

    }
}

1.1List接口方法

1.集合元素有序,可以重复

2.每个元素都有对应顺序的索引

3.List容器中的元素都对应一个整数型的序号记载其在容器的位置,可以根据序号存取容器中的元素

package collection;

import java.util.ArrayList;

public class List {
    public static void main(String[] args) {
        ArrayList List1 = new ArrayList();
        List1.add("JACK");
        List1.add("sparrow");
        List1.add("Tom");
        List1.add("Tom");
        System.out.println("List1="+List1);//List1=[JACK, sparrow, Tom, Tom]
        System.out.println(List1.get(0));//取出第一个元素,索引是从0开始的
        
     }
}

 操作集合元素的方法

package collection;

import java.util.ArrayList;
import java.util.List;
public class ListMethod {
    public static void main(String[] args) {
       List List1 = new ArrayList();
       List1.add("q");
       List1.add("w");
       List1.add(1,"p");//在index=1,也就是q中插入"p",插入一个元素
        System.out.println(List1);//[q, p, w]

        ArrayList List2 = new ArrayList();
        List2.add("S");
        List2.add("a");
        List1.addAll(1,List2);//在q中插入S,a,插入多个元素
        System.out.println(List1);//[q, S, a, p, w]

        System.out.println(List1.get(2));//获取指定位置元素,这里是第三个元素位置也就是a

        System.out.println(List1.indexOf("a"));//2 a在集合中首次出现的位置

        System.out.println(List1.lastIndexOf("w"));//4 w在集合中末次出现的位置

        List1.remove(2);//删除一个元素值,在这里是删除了一个
        System.out.println(List1);

        List1.set(2,"e");//将第三个元素值替换成e
        System.out.println(List1);

        //List returnlist=List1.subList(1,3);//返回的是下标1和下标(3-1)也就是下标2
        List1.subList(1,3);
       // System.out.println("returnlist="+returnlist);
        System.out.println(List1.subList(1,3));
    }
}

1.2List三种遍历方式 

1)方式一:使用iterator

Iterator iter = col.iterator();

while(iter.hasNext()){

Object o = iter.next();

}

2)方式二:使用增强for

for(Object o:col){
}

3)方式三:使用普通for

for(int i=0;i<list.size();i++){
 Object object=list.get(i);
 System.out.println(object);
}

 Tips:

         使用LinkedList完成 使用方式和ArrayList一样

package collection;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListFor {
    public static void main(String[] args) {
       List List = new ArrayList();
       List.add("jack");
       List.add("p");
       List.add("y");
       List.add(10);
       //遍历
        //1.迭代器
        Iterator iterator = List.iterator();
        while(iterator.hasNext()){
            Object obj=iterator.next();
            System.out.println(obj);
        }
        System.out.println("===========");
        //2.增强for(用大写的I回车)
        for (Object o :List) {
            System.out.println("o="+o);
        }
        System.out.println("=============");
        //3.普通for循环
        for(int i=0;i<List.size();i++){
            Object object = List.get(i);
            System.out.println(object);
        }

    }
}

1.2.1 ArrayList 

1.permits all elements,including null,ArrayList可以加入null,ArrayList可以加入null,并且有多个

2.ArrayList是由数组来实现数据存储的

3.ArrayList基本等同于Vector,除了ArrayList是线程不安全(执行效率高)看源码,在多线程情况下,不建议使用ArrayList

package collection;

import java.util.ArrayList;
@SuppressWarnings({"all"})
public class ArrayListDetail {
    public static void main(String[] args) {
        ArrayList arrayList = new ArrayList();
        arrayList.add(null);
        arrayList.add("jack");
        arrayList.add(null);//可以放多个空值
        System.out.println(arrayList);//[null, jack, null]
    }
}

1.2.2 ArrayList底层结构和源码分析

1)ArrayList中维护了一个Object类型的数组elementData. transient Object[]elementData;

2)当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData容量为0,第一次添加,则扩容elementData为10,如需要再次扩容,则扩容elementData容量为1.5倍

3)若使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍

1.3 Vector

1)Vector类的定义说明

public class Vector<E>
extends AbstractList<E>
implements List<E>,RandomAccess,Cloneable,Serializable

2)Vector底层也是一个对象数组,protected Object[] elenmentData;

3)Vector是线程同步的,即线程安全,Vector类的操作方法带有synchronized

public synchronized E get(int index){
 if(index>=elementCount)
    throw new ArrayIndexOutOfBoundsException(index);
 return elementData(index);
}

4)在开发中,需要线程同步安全时,考虑使用Vector

1.3.1 Vector底层结构和源码分析

1.如果是无参,默认10,满后,就按2倍扩充,如果指定大小,则每次直接按2倍扩

package list;
import java.util.Vector;
public class Vector_{
    public static void main(String[] args) {
        //无参构造器
    Vector vector= new Vector();
        for(int i=0;i<10;i++){
            vector.add(i);
        }
        //源码解读
        //1.new Vector()底层
        /*
         public Vector(){
         this(10);
         }
         //2.vector.add(i)
         2.1 下面这个方法就添加数据到vector集合
            public synchronized boolean add(E e){
              modCount++;
              ensureCapacityHelper(elementCount + 1);
              elementData[elementCount++] = e;
              return true;
            }
            2.2//确定是否需要扩容 条件:minCapacity - elementData.length > 0
                private void ensureCapacityHelper(int minCapacity) {
        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }
            2.3//如果需要的数组大小 不够用,就扩容,扩容的算法
               //int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
               // capacityIncrement : oldCapacity);
              private void grow(int minCapacity) {
        // overflow-conscious code
        int oldCapacity = elementData.length;
        int newCapacity = oldCapacity + ((capacityIncrement > 0) ?
                                         capacityIncrement : oldCapacity);
        if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        elementData = Arrays.copyOf(elementData, newCapacity);
    }
         */
        
    }

}

1.4 LinkedList

1.LinkedList底层实现了双向链表和双端队列特点

2.可以添加任意元素(元素可以重复),包括null

3.线程不安全,没有实现同步

1.4.1 LinkedList底层结构

1.LinkedList底层维护了一个双向链表

2.LinkedList中维护了两个属性first和last分别指向 首节点和尾节点

3.每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点。最终实现双向链表。

4.所以LinkedList的元素的添加和删除,不是通过数组完成的,相对来说效率较高

5.模拟一个简单的双向链表

package list;

public class LinkedList01 {
    public static void main(String[] args) {
        //模拟一个简单的双向链表

        Node jack = new Node("jack");
        Node Tom = new Node("Tom");
        Node merry = new Node("merry");
        //连接三个结点,形成双向链表
        //jack->Tom->merry
        jack.next =Tom;
        Tom.next = merry;
        //merry->Tom->jack
        merry.pre = Tom;
        Tom.pre = jack;
        Node first = jack;//让first引用指向jack,就是双向链表的头
        Node last = merry;//让last引用指向merry,双向链表的尾

    }
}
//定义一个Node类,Node对象 表示双向链表的一个节点
class Node{
    public Object item;//真正存放数据
    public Node next;//指向后一个节点
    public Node pre;//指向前一个节点
    public Node(Object name){
        this.item = name;
    }
    public String toString(){
        return "Node name="+item;
    }
}

2.1 Set接口和常用方法

 1.Set接口基本介绍

1)无序,没有索引

2)不允许重复元素,所以最多包含一个null

2.Set接口常用方法

1)和List接口一样,也是Collection的子接口,因此,常用方法和Collection接口一样

3.Set接口遍历方法

1)可以使用迭代器

2)增强for

3)不能使用索引的方式来获取

package collection.set_;

import javafx.beans.binding.ListExpression;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class SetMethod {
    public static void main(String[] args) {
        //1. 以Set接口的实现类 HashSet
        //2.set接口的实现类的对象(Set接口对象),不能存放重复元素,但可以有null
        //3.set接口对象存放数据是无序
        //4.注意:取出的顺序是一定的虽然不是添加的顺序,但是是固定的
        Set set = new HashSet();
        set.add("john");
        set.add("lucy");
        set.add("john");//重复
        set.add("jack");
        set.add(null);
        set.add(null);//再次添加null
        System.out.println(set);//[null, john, lucy, jack]
        //遍历
        //方式1:使用迭代器
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            Object obj=iterator.next();
            System.out.println(obj);
        }
        //方式2:增强for
        for (Object o :set) {
            System.out.println("o="+o);
        }
        //set接口对象,不能通过索引来获取

    }
}

2.1.1 HashSet

1.实现了Set接口

2.HashSet实际上是HashMap

3.可以存放null值

4.HashSet不保证元素是有序的,取决于hash后,在确定索引的结果

5.不能有重复元素或对象

package collection.set_;
import java.util.HashSet;
public class HashSet01 {
    public static void main(String[] args) {
        HashSet set = new HashSet();
        //1.在执行add方法后,会返回一个Boolean值
        //2.添加成功为true 失败为false
        //3.可以通过remove指定删除对象
        System.out.println(set.add("john"));
        System.out.println(set.add("jack"));
        System.out.println(set.add("merry"));
        System.out.println(set.add("john"));//如果添加失败会返回一个false//false
        set.remove("john");
        System.out.println(set);
    }
}

2.1.2 HashSet底层机制

1.HashSet底层是HashMap

2.添加一个元素时,先得到Hash的值,会转成->索引值

3.找到存储数据表table,看这个索引位置是否已经存放的有元素

4.如果没有,直接加入

5.如果有,调用equals比较,如果相同就放弃添加,如果不同就添加到最后

2.2 LinkedHashSet

1.LinkedHashSet是HashSet的子类

2.LinkedHashSet底层是一个LinkedHashMap,底层维护了一个数组+双向链表

3.LinkedHashSet根据元素的hashCode值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的

4.LinkedHashSet不允许添加重复元素

package collection.set_;
import java.util.LinkedHashSet;
import java.util.Set;
public class LinkedHashSetSource {
    public static void main(String[] args) {
        Set set = new LinkedHashSet();
        set.add(new String("AA"));
        set.add(456);
        set.add(new Coustomer("li",1001));
        set.add(123);
        System.out.println(set);
    }
}
class Coustomer{
    private String name;
    private int id;
    public Coustomer(String name,int id){
        this.name=name;
        this.id=id;
    }
}

2.3 TreeSet 

package collection.set_;

import java.util.Comparator;
import java.util.TreeSet;

public class TreeSet_ {
    public static void main(String[] args) {
        //1.当使用无参构造器,创建treeSet,仍然是无序的
        //2.将添加的元素按照字符串大小排序
        //3.使用TreeSet提供的一个构造器,可以传入一个比较器(匿名内部类)
        //并指定排序规则

      //  TreeSet treeSet = new TreeSet();
       TreeSet treeSet = new TreeSet(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                //下面调用String的compareTo方法进行字符串大小比较
                return ((String)o2).compareTo((String) o1);
            }
        });
        //添加数据
        treeSet.add("jack");
        treeSet.add("tom");
        treeSet.add("sp");
        treeSet.add("y");
        System.out.println(treeSet);//[y, tom, sp, jack]
    }

}

3.1 Map接口

1.Map与Collection并列存在,用于保存映射关系的数据

2.Map中的key和Value可以是任何引用类型的数据,会封装到HashMap$Node对象中

3.Map中的key不允许重复

4.value可以重复

5.key可以为null,value也可以为null,且有多个,key为null只能有一个

6.常用String类作为key

7.key和Value之间存在单向一对一的关系

package map;

import java.util.HashMap;
import java.util.Map;

public class Map_ {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("no1","zhang");
        map.put("no2","han");
        map.put("no1","peng");//用新的值替换zhang//结果为peng
        System.out.println(map);//{no2=han, no1=peng}
    }
}

 3.2 Map常用方法(例子为HashMap):

1.put :添加

2.remove:根据删除键删除映射关系

3.get:根据键获取值

4.size:获取元素个数

5.isEmpty:判断个数是否为0

6.clear:清除

7.containsKey:查找键是否存在

package map;

import java.awt.print.Book;
import java.util.HashMap;
import java.util.Map;
public class MapMethod {
    public static void main(String[] args) {
        //常用方法
        Map map = new HashMap();
        map.put("邓超",new Book1 ("",100));
        map.put("邓超","孙俪");//替换了,也就是说邓超这个时候对应孙俪了而不是一本书
        map.put("王金","马蓉");
        map.put("张哲","马蓉");
        map.put("刘星","null");
        map.put("null","刘亦菲");
        map.put("陆星","徐妍");
        map.put("peng","X");
        System.out.println(map);//{邓超=孙俪, null=刘亦菲, 王金=马蓉, 张哲=马蓉, 陆星=徐妍, 刘星=null}
        map.remove("邓超");//也可以写成"邓超","孙俪"
        System.out.println(map);//{null=刘亦菲, 王金=马蓉, 张哲=马蓉, 陆星=徐妍, 刘星=null}
        map.remove("null");
        System.out.println(map);//{王金=马蓉, 张哲=马蓉, 陆星=徐妍, 刘星=null}
        map.get("王金");
        System.out.println(map.get("王金"));//获取王金对应的值:马蓉
        System.out.println(map.size());//获取元素个数:4
        System.out.println(map.isEmpty());//判断个数是否为0:false
       // map.clear();
        System.out.println(map);//{}
        System.out.println(map.containsKey("peng"));//如果不进行clear,为true,若进行,为false

    }
}
class Book1{
    private String name;
    private int num;
    public Book1(String name,int num) {
        this.name = name;
        this.num = num;
    }
}

 3.2.1 遍历方法

public class MapMethod {
    public static void main(String[] args) {
        //常用方法
        Map map = new HashMap();
        map.put("邓超",new Book1 ("",100));
        map.put("邓超","孙俪");//替换了,也就是说邓超这个时候对应孙俪了而不是一本书
        map.put("王金","马蓉");
        map.put("张哲","马蓉");
        map.put("刘星","null");
        map.put("null","刘亦菲");
        map.put("陆星","徐妍");
        map.put("peng","X");
        //第一组先取出所有的Key,通过Key取出对应的Value
        Set keyset = map.keySet();
        //(1)增强for
        System.out.println("======第一种方式======");
        for (Object key: keyset) {
            System.out.println(key+"-"+map.get(key));
        }
        //(2)迭代器
        System.out.println("======第二种方式======");
        Iterator iterator = keyset.iterator();
        while(iterator.hasNext()){
            Object key = iterator.next();
            System.out.println(key+"-"+map.get(key));
        }
        //第二组:把所有的values取出
        Collection values  = map.values();
        //可以使用所有的Collection使用的遍历方法
        //(1)增强for
        System.out.println("=====取出所有的value======");
        for(Object value : values){
            System.out.println(value);
        }
        //(2)迭代器
        System.out.println("=====取出所有的value 迭代器====");
        Iterator iterator2 = values.iterator();
        while (iterator2.hasNext()){
            Object value = iterator2.next();
            System.out.println(value);
        }
        //第三组:通过EntrySet来获取k-v
        Set entrySet = map.entrySet();
        //(1)增强for
        for(Object entry : entrySet){
            //将entry转换成Map.Entry
            System.out.println(entry);
        }
        //(2)迭代器
        Iterator iterator3 = entrySet.iterator();
        while (iterator3.hasNext()){
            Object entry = iterator3.next();
            System.out.println(entry);
        }
        

3.2.2 HashMap底层机制

1.底层维护了Node类型的数组table,默认为null

2.当创建对象时,将加载因子初始化为0.75

3.当添加key-val时。通过key的哈希值得到在table的索引,然后判断是否有元素,如果没有直接添加,如果有,继续判断该元素的key是否和准备加入的key相等,如果相等,则直接替换成val;如果不相等需要判断是树结构还是链表结构,如果发现容量不足,则需要扩容

4.第一次添加,扩容table量为16,临界值为12

5.以后再扩容,则需要扩容table容量为原来的2倍,临界值为原来的2倍,也就是24

3.3 Hashtable

1.基本介绍(例子中包含Hashtable扩容)

1)存放的元素是键值对:即K-V

2)hashtable的键和值都不能为null

3)hashTable使用方法基本上和HashMap一样

4)hashTable是线程安全的,hashMap是线程不安全的

package map;
import java.util.Hashtable;
public class HashTableExercise {
    public static void main(String[] args) {
        Hashtable table = new Hashtable();
        table.put("john",100);
       // table.put(null,100);//显示异常 NullException
       // table.put("john",null);//显示异常 NullException
        table.put("lucy",100);
        table.put("lic",100);
        table.put("lic",88);//替换了,将以88替换成100
        System.out.println(table);
        table.put("hello1",1);
        table.put("hello2",1);
        table.put("hello3",1);
        table.put("hello4",1);
        table.put("hello5",1);
        table.put("hello6",1);
        System.out.println(table);

        //Hashtable的底层
        //1.底层有数组 Hashtable$Entry[] 初始化大小为11
        //2.临界值 threshod 8 = 11 * 0.75
        //3.扩容:按照自己的想法扩容进行就可以
    }

}

3.4 TreeMap

package map;

import java.util.Comparator;
import java.util.TreeMap;

public class TreeMap_ {
    public static void main(String[] args) {
        //使用默认构造器,创建TreeMap,是无序的
       // TreeMap treeMap = new TreeMap();
        TreeMap treeMap = new TreeMap(new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                //按照传入的大小进行排序
                return ((String)o2).compareTo((String)o1);//按照首字母顺序 t,s,k 从大到小
            }
        });
       // treeMap.put("jack",new Book2(  "A",100));
        treeMap.put("tom","汤姆");
        treeMap.put("kris","克瑞斯");
        treeMap.put("smith","史密斯");
        System.out.println(treeMap);
    }
}
class Book2{
    private String name;
    int price;
    public Book2(String name,int price){
        this.name=name;
        this.price=price;
    }


}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值