liujijiang

java学习笔记 --11-- 持有对象

2020.03.29

持有对象

java容器:

  • Collection
    • List
      • ArrayList
      • LinkedList
    • Set
      • HashSet
      • TreeSet
      • LinkedHashSet
    • Queue
  • Map
    • HashMap
    • TreeMap
    • LinkedHashMap

容器的一些特性例如Set每个值只能保存一个对象,Map允许对象与对象之间关联
java容器可以自动调整尺寸

容器和泛型

通过向上转型放到泛型容器中

package com.company;

import java.util.ArrayList;
import java.util.List;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{
    
    public static void main(String [] args){
        List<Test1> list = new ArrayList<>();
        
        list.add(new Test1());
        list.add(new Test2());
        list.add(new Test3());
    }
}

class Test1{
    
}
class Test2 extends Test1{
    
}
class Test3 extends Test2{
    
}

通过向上转型,子类也可以放到容器中

基本概念

java中容器的目的是保存对象

  • Collection
    • List:按照插入的顺序保存元素
    • Set:不能有重复元素
    • Queue:按照自定义规则排序对象
  • Map:存储键值对对象,可以通过键查找值,

初始化容器

	public static void main(String [] args){
        List<String> list = new LinkedList<>();
        LinkedList<String> linkedList = new LinkedList<>();
    }

这两种初始化是有区别的:
第一种:向上转型,list可以使用List中声明LinkedList中实现的方法,但是ListedList中有一部分方法是List中没有声明的,所以这种初始化方法就不能使用这些方法
第二种:可以使用ListedList中所有的方法

序列:一种存放一组对象的方式

public static void main(String [] args){
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        System.out.println(list.toString());

        Collection<Integer> collection = new ArrayList<>();
        collection.addAll(Arrays.asList(1,2,3,4,5));
        Collections.addAll(collection,6,7,8,9,0);
    }

Arrays.asList方法接受一个数组或一个逗号分隔的元素列表,返回List对象
Collections.addAll方法传入collection和逗号分隔的元素列表
Collections.addAll方法更快,所以首选

List

  • ArrayList
    擅长随机访问,但是插入删除比较慢
  • LinkedList
    插入删除快,特性集多,访问慢

list中的操作都依赖于***equals***方法(所有的操作都是对值进行判断,而不是引用)

package com.company;

import java.util.*;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void main(String [] args){
        List<String> list = new ArrayList<>();
        list.add("1");
        list.add(0,"123");
        list.add("123");
        List<String> list1 = new ArrayList<>();
        list1.add("123");
        list1.add("456");
        System.out.println(list.retainAll(list1));
        System.out.println(list.toString());
        System.out.println(list.contains("123"));
        Collections.sort(list);
        list.set(0,"jjboy");
        list.containsAll(list1);
        System.out.println(list.subList(0,2));
        System.out.println(list.indexOf("123"));
        System.out.println(list.remove("123"));
        System.out.println(list.remove("123"));
        System.out.println(list.contains("123"));
	String [] strings =list.toArray(new String [0]);
        list.clear();
        System.out.println(list.isEmpty());
    }

}


retainAll():返回一个boolean值,并且list的值为两个list的交集
subList(0,2):取出索引为0,1的值返回一个list
如果list中有重复的值:indexof 返回第一个值的索引,remove删除的也是第一个,contains的值为true
方法中带all 和不带all:带all 参数为一个list 不带all 参数为一个对象

迭代器

一个对所有容器通用的对象
迭代器:一个对象,可以遍历并选择序列中的对象,被称作轻量级对象
java迭代器只能单向移动

package com.company;

import java.util.*;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void main(String [] args){
        List<String> list = Arrays.asList("123","456","789");
        Iterator<String> iterator = list.iterator();
        System.out.println(iterator.hasNext());
        System.out.println(iterator.next());
        System.out.println(iterator.next());

    }

}


初始化后:.next()返回第一个元素
hasnext():判断是否有下一个元素

威力:将遍历操作和容器的数据接口分离,同意了容器的遍历方式

ListIterator是Iterator的子类型,只能用于List,功能更强大

package com.company;

import java.util.*;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void main(String [] args){
        List<String> list = Arrays.asList("123","456","789");
        ListIterator<String> iterator = list.listIterator();
        ListIterator<String> iterator1 = list.listIterator(1);

        System.out.println(iterator.hasNext());
        System.out.println(iterator.next());
        System.out.println(iterator.nextIndex());
        System.out.println(iterator.hasPrevious());
        System.out.println(iterator.previous());
        System.out.println(iterator.previousIndex());
        iterator.set("789");
        System.out.println(iterator.next());

        System.out.println(iterator1.nextIndex());

    }

}


ListIterator:一个针对List的可以双向移动的迭代器
个人感觉可以怎么理解:迭代器只能指向两个数据的间隙,初始化后指向第一个数据之前的间隙
next:返回下一个数据元素并移动至下一个数据后面的间隙
previous:返回前一个数据并移动到前一个数据之前的间隙
初始化时可以指定位置初始化
set:移动到参数对象之前的间隙,这样next返回的就是这个参数对象

LindedList

package com.company;

import java.util.*;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void main(String [] args){
        LinkedList<String> list = new LinkedList<>();
        Collections.addAll(list,"123","456","789");
        System.out.println(list.peek());
        System.out.println(list.peekFirst());
        System.out.println(list.peekLast());
        System.out.println(list.getFirst());
        System.out.println(list.getLast());
        System.out.println(list.element());
        System.out.println(list.remove());
        System.out.println(list.removeFirst());
        System.out.println(list.removeLast());
        System.out.println(list.add("123"));

        System.out.println(list.toString());

    }

}

get remove 方法和 peek poll 方法返回的结果一样,区别是如果没有元素前者抛出NoElementException异常,后者返回null
getFirst和element完全一样

Stack

栈:LIFO(后进先出)

package com.company;

import java.util.*;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void main(String [] args){
        Stack<String> stack = new Stack<>();

        Collections.addAll(stack,"123","456","789");

        System.out.println(stack.peek());
        System.out.println(stack.pop());
        System.out.println(stack.push("123"));
        System.out.println(stack.toString());
    }

}


peek返回栈顶元素
pop返回并删除栈顶元素

Set

set不保存重复元素
HashSet:使用散列函数,元素无顺序
TreeSet:使用红黑树,元素有顺序
LinkedHashSet:使用散列函数,但是使用LinkedList维护元素顺序

package com.company;

import com.sun.source.util.Trees;

import java.util.*;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void main(String [] args){
        Set<String > set = new HashSet<>();

        Collections.addAll(set,"123","456","789");
        System.out.println(set.contains("123"));

        Set<String> treeSet = new TreeSet<>();

        Collections.addAll(treeSet,"Abcd","abcd","dcbd","bcda");
        System.out.println(treeSet.toString());
    }

}


TreeSet默认按照首字母排序

Map

package com.company;

import com.sun.source.util.Trees;

import java.util.*;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void main(String [] args){
        Random random = new Random(10);
        Map<Integer,Integer> map = new HashMap<>();
        for(int i=0;i<1000;i++){
            Integer a = random.nextInt(20);
            map.put(a,map.containsKey(a)?map.get(a)+1:1);
        }
        System.out.println(map);
        System.out.println(map.keySet());
        System.out.println(map.values());
        System.out.println(map.isEmpty());
        System.out.println(map.size());
        System.out.println(map.get("1"));
        
    }

}


使用map观察随机函数

Queue

队列:FIFO(先进先出),在并发编程中比较重要
LinkedList实现了Queue接口,所以LinkedList可以向上转型为Queue
Queue接口窄化了LinkedList实现,使得只有一部分Queue方法可以使用

package com.company;

import com.sun.source.util.Trees;

import java.util.*;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void main(String [] args){
        Queue<String> queue = new LinkedList<>();

        Collections.addAll(queue,"123","456","789");

        System.out.println(queue.peek());
        System.out.println(queue.element());
        System.out.println(queue.poll());
        System.out.println(queue.remove());
        System.out.println(queue.add("123"));
        System.out.println(queue.offer("332"));
        System.out.println(queue);
    }

}


peek element:查看队首元素,不删除,如果为空,peek返回null,element抛出NoElementException异常
poll remove:返回并删除队首元素,如果为空,poll返回null,remove抛出NoElementException异常
offer:条件允许情况下,队尾添加元素

PriorityQueue

普通队列的出队规则是在队列中能带时间最长的元素
优先队列:最重要的元素出队(优先级高的先出队)

package com.company;

import com.sun.source.util.Trees;

import java.util.*;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void main(String [] args){
        PriorityQueue<Integer> queue = new PriorityQueue<>();
        PriorityQueue<Integer> queue1 = new PriorityQueue<>(Collections.reverseOrder());

        Collections.addAll(queue,1,2,3,2,3,2,1,1);
        Collections.addAll(queue1,1,2,3,3,3,2,2,1,2,1);

        System.out.println(queue);
        System.out.println(queue1);
    }

}

元素可以重复,默认排序从小到大,可以在新建的时候传参Collections.reverseOrder改变排序方式
如果是String空格是最小的

Collection和Iterator

Collection是所有的序列容器的共性跟接口,他有一个默认的实现AbstractCollection

Foreach

package com.company;

import com.sun.source.util.Trees;

import java.util.*;

/**
 * @ClassName Test
 * @Description
 * @Auther liuxiansen
 * @Date 2020/3/29 8:55 上午
 **/
public class Test{

    public static void main(String [] args){
        Collection<String> list = new LinkedList<>();

        Collections.addAll(list,"jjboy vip is a good website".split(" "));

        for(String s : list){
            System.out.println(s);
        }

        for(Map.Entry entry : System.getenv().entrySet()){
            System.out.println(entry.getKey() + " : " + entry.getValue());
        }
    }

}


总结

  • 数组将数字和对象联系起来,数组一旦创建容量就不能变了
  • List提供了数字索引与对象之间的关联
  • 如果需要大量访问用ArrayList,如果需要频繁插入删除用LinkedList
  • 各种的Queue和Stack用LinkedList提供支持
  • Map是对象与对象之间的关联,HashMap提供快速访问,TreeMap保持键的顺序,LinkedListMap保持键的顺序为插入的顺序并提供了快速访问
  • Set元素不能重复,HashSet TreeSet LinkedListSet跟Map类似
  • 不要使用过时的Vector,HashTable,Stack
  • 除了TreeSet之外Set与Collection拥有一样的接口
  • Map和Collection之间唯一的重叠部分Map可以使用keySet和values生成Collection,entrySet生成key=value形式的Collection

Unknown.jpg