zoukankan      html  css  js  c++  java
  • Collection与Map

    一、collection框架

     (1)LIST

    list是一种collection,作用是收集对象,并以索引的方式保留收集的对象的顺序。其操作类之一就是Java.utl.ArrayList.ArrayList特性:随机查找(list.get[i]),ArrayList内部就是用Object来保存收集的对象。此时就考虑到了数组的特性。根据数据结构内容我们只数组的好处就是随机存储速度快,排序等就可以考虑使用ArrayList

    package Learn;
    
    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Scanner;
    
    public class ListDemo {
        public static void main(String[] args) {
            List name=new ArrayList();//收集信息的list
            collectNameTo(name);//收集函数
            System.out.println("输出访客名单:");
            printUpperCase(name);//输出收集到的信息
        }
        /**
         *@author wbm
         *@param List
         *@deprecated通过控制台输入访客的名称,如果遇到quit则退出输入访客名称的循环,每次循环都把收集到的信息通过List.add(信息对象)收集到list中去
         */
            
        
         static void collectNameTo(List names){
            Scanner console=new Scanner(System.in);//控制台输入信息
            while(true){
                System.out.println("访客名称:");
                String name=console.nextLine();
                if(name.equals("quit")){
                    break;
                }
                names.add(name);//把控制台输入的信息放入到list中去
            }
        }
         /**
          *通过for循环把传进来的List通过索引获取list元素并转换为string性,然后通过string的toUpperCase()转为大写
          */
         static void printUpperCase(List names){
             for (int i = 0; i < names.size(); i++) {
                String name=(String) names.get(i);//通过索引获得收集的信息
                System.out.println(name.toUpperCase());
    
             }
         }
    
    }
    View Code

    LinkedList特性:采用链接结构。链接结构简单代码如下。

    package Learn;
    
    public class LinkListDemo {
        private class Node{
            Object o;
            Node next;
            Node(Object o){
                this.o=o;
            }
        }
        private Node first;
        public void add(Object elem){
            Node node=new Node(elem);
            if(first==null){
                first=node;
            }
            else{
                append(node);
            }
        }
        private void append(Node node){
            Node last=first;
            while(first.next!=null){
                last=last.next;
            }
            last.next=node;
        }
        public int size(){
            int count=0;
            Node last=first;
            while(last.next!=null){
                last=last.next;
                count++;
            }
            return count;
        }
        public Object get(int index){
            checkSize(index);
            return findElemof(index);
        }
        private void checkSize(int index)throws IndexOutOfBoundsException{
            int size=size();
            if(index>=size){
                throw new IndexOutOfBoundsException( String.format("index:%d size:%d", index,size));
                
            }
        }
        private Object findElemof(int index){
            int count=0;
            Node last=first;
            while(count<index){
                last=last.next;
                count++;
            }
            return last.next;
        }
    
    }
    View Code

      (2)set

     也是收集对象,但是对象相同则不重复收集。知道不重复单词个数有几个代码如下。

    public static void mian(String[] args) {
            // TODO Auto-generated method stub
            Scanner scanner=new Scanner(System.in);
            System.out.println("请输入英文");
            Set words=tokenSet(scanner.nextLine());//scanner.nextLine()String类型
            System.out.printf("不重复的字有%d个:%s%n",words.size(),words);
        }
        static Set tokenSet(String line){
            String[] tokens=line.split(" ");//根据空白切割字符串
            return new HashSet(Arrays.asList(tokens));//使用HashSet收集字符串
            
        }
    View Code

    使用set时得告诉怎样的对象是相同,这时要用对象的hashCode()和equals()来判断对象是够相同。HashSet的操作哦该娘是,在内存中开设空间,每个空间都会有哈希编码,这些空间称为哈希桶,如果对象要加入哈希桶,则要调用对象的hashcode(),并尝试放入对应的哈希桶中,如果哈希桶中没有对象就放入,如果有对象就调用equals()进行比较。有无equals和hashcode的对比代码如下

    package Learn;
    
    import java.util.HashSet;
    import java.util.Set;
    
     class Student {
        private String name;
        private String number;
        Student(String name,String number){
            this.name=name;
            this.number=number;
        }
        @Override
        public String toString() {
            return "Student [name=" + name + ", number=" + number + "]";
        }
    
        
    }
    
    package Learn;
    
    import java.util.HashSet;
    import java.util.Set;
    
    public class Students {
        
            public static void main(String[] args) {
                Set students=new HashSet();
                students.add(new Student("b","c"));
                students.add(new Student("b","c"));
                students.add(new Student("q","c"));
            System.out.println(students);
    
        }
    
    }
    结果:
    [Student [name=q, number=c], Student [name=b, number=c], Student [name=b, number=c]]
    package Learn;
    
    import java.util.HashSet;
    import java.util.Set;
    
     class Student {
        private String name;
        private String number;
        Student(String name,String number){
            this.name=name;
            this.number=number;
        }
        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            result = prime * result + ((number == null) ? 0 : number.hashCode());
            return result;
        }
        @Override
        public boolean equals(Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Student other = (Student) obj;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            if (number == null) {
                if (other.number != null)
                    return false;
            } else if (!number.equals(other.number))
                return false;
            return true;
        }
        @Override
        public String toString() {
            return "Student [name=" + name + ", number=" + number + "]";
        }
        
    }
    结果:
    [Student [name=b, number=c], Student [name=q, number=c]]
    View Code

    java.util.TreeSet不仅有收集不重复对象的能力,还可以用红黑树的方式排序收集到的对象,条件就是收集到的对象必须是Comparable(否则会抛出ClassCastException),或者是在创建的是后指定comparator对象

     (3)quene

    支持队列操作,收集的对象加入至尾部,取得的对象时从前部,quene继承自collection所以有add、remove、element等方法然而quene定义了自己的offer、poll、peak等方法主要区别在于,add、remove、element等方法操作失败时会抛出异常,而offer、poll、peak会返回特定的值。对象需要使用队列且长度受限是用通常使用poll、offer、peak方法。从架构图可知linkedList不仅操作了queue的行为也操作了list的行为。所以可以将linkedlist当做队列来使用。

    简单的代码实例如下:

    package Learn;
    
    public interface Request {
         void execute();
    
    }
    
    package Learn;
    
    import java.util.*;
    /**
     * offer是在队列前端加入对象成功会返回trues失败会返回false。
     * poll是去除队列的前端对象,若队列为空则返回null。
     * peak是取得前端对象但是不取出若为空则返回null。
     * */
    public class RequestQuene{
        public static void main(String[] args) {
            Queue requests=new LinkedList();
            offerRequestTo(requests);
            process(requests);
        }
        static void offerRequestTo(Queue requests){
            //请求加入队列
            for(int i=1;i<6;i++){
                Request request=new Request(){
                    @Override
                    public void execute() {
                        // TODO Auto-generated method stub
                        System.out.printf("处理数据%f%n",Math.random());
                    }
                };
                requests.offer(request);
                System.out.println(requests.offer(request));
            }
        }
        static void process(Queue requests){
            //处理队列中的请求
            while(requests.peek()!=null){
                Request request=(Request)requests.poll();
                request.execute();
            }
        }
        
    }
    View Code

    如果想要对队列的前端和尾端进行操作,在前端加入对象和取出对象,在尾端加入对象和取出对象,queue的子接口Deque就定义了该行为。deque中定义addFirst()、removeFirst()、getFirst()、addLast()、

    removeLast()、getLast()等方法,操作失败时会抛出异常。而offerFirst()、pollFirst()、peekFirst()、offerLast()、pollLast()、peekLast()操作失败会返回特定的值。java.util.ArrayDeque操作了Deque接口,操作使用容量有限的堆栈的简单实例如下

    package Learn;
    
    import java.util.*;
    
    public class Stack {
        private Deque elems=new ArrayDeque();
        private int capacity;
        Stack(int capacity){
            this.capacity=capacity;
        }
        public boolean push(Object elem){
            if(isFull()){
                return false;
            }
            else{
                return elems.offerLast(elem);
            }
        }
        private boolean isFull(){
            return elems.size()+1>capacity;
        }
        public Object pop(){
            return elems.pollLast();
        }
        public Object peek(){
            return elems.peekLast();
        }
        public int size(){
            return elems.size();
        }
        public static void main(String[] args) {
            Stack stack=new Stack(5);
            stack.push("justin");
            stack.push("wbm");
            stack.push("wcy");
            System.out.println(stack.pop());
            System.out.println(stack.pop());
            System.out.println(stack.pop());
        }
    
    }
    结果:
    wcy
    wbm
    justin
    堆栈是先进后出
    View Code

    queue的操作类之一java.util.PriorityQueue也是,收集至PriorityQueue的对象,会根据你指定的优先权来决定对象在队列中的顺序,优先的告知,要不是对象必须是comparable,或者是在创建PriorityQueue时指定comparator对象。

    (3)Interable与Iterator

    iterator方法JDK5之前是定义在collection中在JDK5之后定义在iterable;具体的一些好处和细节如下代码。

        //收集LIst对象
        static void forEachList(List list){
            int size=list.size();
            for(int i=0;i<size;i++){
                System.out.println(list.get(i));
            }
        }
        //收集set对象
        static void forEachSet(Set set){
            for(Object o:set.toArray()){
                System.out.println(o);
            }
        }
        //收集queue对象
        static void forEachQueue(Queue queue){
            while(queue.peek()!=null){
                System.out.println(queue.poll());
            }
        }
        //含有这个方法的类是util,那么你就可以指定使用util.<String> elemOf()的方式指定E的实际类型
        public static<E> E elemOf(E[] objs,int index){
            return objs[index];
        }
        //无论是Queue、List、Set都会有iterator方法JDK5之前是定义在collection中在JDK5之后定义在iterable
        static void forEachCollection(Collection collection){
            Iterator iterator=collection.iterator();
            while(iterator.hasNext()){
                System.out.println(iterator.next());
            }
        }
        static void forEachIterable(Iterable iterable){
            Iterator iterator=iterable.iterator();
            while(iterator.hasNext()){
                System.out.println(iterator.next());
            }
        }
    View Code
    package Learn;
    
    import java.util.ArrayDeque;
    import java.util.Arrays;
    import java.util.HashSet;
    import java.util.List;
    
    public class forEach {
        public static void main(String[] args) {
            List names=Arrays.asList("ww","bb","mm");//静态方法aslist接收不定长自变量将其指定为List
            forEach(names);//list是一种Iterable.
            forEach(new HashSet(names));//List是一种collection,hashSet是一种collection接收collection的构造函数所以list可以用来创建hashset
            forEach(new ArrayDeque(names));//同理
        }
        static void forEach(Iterable iterable){
            for (Object object : iterable) {
                System.out.println(object);
            }
            
        }
    
    }
    View Code

    (4)comparable与comparator

     1. comparable(comparaTo())   

      在收集对象之后,对对象排序是常用的动作,我们不用亲自操作排序算法,java.util.collections

    List numbers=Arrays.asList(10,5,1,9,8,9,7);
            Collections.sort(numbers);
            System.out.println(numbers);
    结果为:[1, 5, 7, 8, 9, 9, 10]
    View Code

      如果没有说明list元素的比较会出现错误

    package Learn;
    
    import java.util.HashSet;
    import java.util.Set;
    
     class Student {
        private String name;
        private String number;
        Student(String name,String number){
            this.name=name;
            this.number=number;
        }
        @Override
        public String toString() {
            return "Student [name=" + name + ", number=" + number + "]";
        }
    }
    
    package Learn;
    
    import java.util.Arrays;
    import java.util.Collections;
    
    import java.util.List;
    
    
    public class Students {
            public static void main(String[] args) {
                List students=Arrays.asList(new Student("b","c"),new Student("b","c"),new Student("q","c"));
                Collections.sort(students);
            System.out.println(students);
    
        }
    }
    出现:
    java.lang.ClassCastException:
    View Code

    collections.sort()的操作对象必须操作java.lang.comparable接口,这个接口有compareTo()方法的返回值必须大于0,等于0或小于0的整数。

    package Learn;
    
    import java.util.HashSet;
    import java.util.Set;
    
     public class Student implements Comparable<Student> {
        private String name;
        private String number;
        Student(String name,String number){
            this.name=name;
            this.number=number;
        }
        @Override
        public String toString() {
            return "Student [name=" + name + ", number=" + number + "]";
        }
        @Override
        public int compareTo(Student o) {
            // TODO Auto-generated method stub
            return Integer.parseInt(this.number)-Integer.parseInt(o.number);
        }
    }
    
    package Learn;
    
    import java.util.Arrays;
    import java.util.Collections;
    
    import java.util.List;
    
    
    public class Students {
            public static void main(String[] args) {
                List students=Arrays.asList(new Student("b","1"),new Student("b","3"),new Student("q","2"));
                Collections.sort(students);
            System.out.println(students);
    
        }
    }
    
    结果为
    [Student [name=b, number=1], Student [name=q, number=2], Student [name=b, number=3]]
    View Code

    2.compatator(compare())

    如果对象无法操作comparable的话呢?比如String本身有操作Comparable,所以可以按字母的排序如果我想要把字母排序的顺序反过来呢?String是final的类型不能被继承所以无法重新定义compareTo()方法。Collection有另一个重载版本,可以接受java.lang.Comparator接口的操作对象。流程:1.定义一个comparator:class StringComparator implements<String>{ public int compare(String s1,String s2){ return s1.compareTo(s2);}}  2.调用:Collections.sort(List,new StringComparator());

    package Learn;
    
    import java.util.Comparator;
    
    public class StringComparator implements Comparator <String> {
    
        @Override
        public int compare(String o1, String o2) {
            // TODO Auto-generated method stub
            return -o1.compareTo(o2);
        }
    
    }
    
    
    package Learn;
    
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    
    public class sort {
        public static void main(String[] args) {
            List<String> words=Arrays.asList("B","A","C");
            Collections.sort(words,new StringComparator());
            System.out.println(words);
        }
    }
    结果
    [C, B, A]
    View Code

    二、Map框架

    1.hashMap

      1)概述

        基于哈希表的Map接口的非同步实现。实现所有的可选映射操作,允许使用null键和null值。此类不保证映射的顺序。

       2)数据结构

      3)简单使用HashMap

    对于Map而言键值是不会重复,判断键是否重复式根据hashcode和equals(),所以作为键的对象必须操作hashcode()与equals()

    public static void main(String[] args) {
            Map<String,String> messages=new HashMap<String,String>();
            messages.put("1", "one");
            messages.put("2", "two");
            messages.put("3", "three");
            Scanner scanner=new Scanner(System.in);
            String message=messages.get(scanner.nextLine());
            System.out.println(message);
            System.out.println(messages);
        }
    结果为:
    1
    one
    {1=one, 2=two, 3=three}
    View Code

    2.TreeMap

      键的部分会排序,条件式作为键的对象必须操作Comparable接口,或者是在创建TreeMap时指定Comparator接口的对象。

        public static void main(String[] args) {
            Map<String,String> messages=new TreeMap<String,String>();
            messages.put("1", "one");
            messages.put("2", "two");
            messages.put("3", "three");
            System.out.println(messages);
        }
    }
    结果为:
    {1=one, 2=two, 3=three}
    View Code

    3.使用Properties

    Properties props=new Properties();
            props.setProperty("username", "justin");
            props.setProperty("password", "123456");
            System.out.println(props.getProperty("username"));
            System.out.println(props.getProperty("password"));
    //从文档中读取属性
    //文档内容a.properties 
    /*
    cc.openhome.username=justin
    cc.openhome.password=123456
    */
    Properties props=new Properties();
            props.load(new FileInputStream("args[0]"));
            System.out.println(props.getProperty("cc.openhome.username"));
            System.out.println(props.getProperty("cc.openhome.password"));
    View Code

    三、简单泛型的使用

      在使用Collection收集对象时,由于事先不知道对象的形态使用的是Object来收集,取回对象也是Object,所以执行期间失去了形态的信息。所以取回对象之后要记得对象的真正的类型,然后让对象重新扮演

      自己的类型。

    List names=Array.asList("ww","bb","mm");
    String name=(String)name.get(0);
    ArrayList<String> names= new ArrayList<String>();
    names.add("justin");
    names.add("wbm");
    names.add(new Long(10));//编译会出错没法通过。
    String name1=names.get(0);
    string nmae2=names.get(1);
    View Code

     静态方法上定义类型

    //含有这个方法的类是util,那么你就可以指定使用util.<String> elemOf()的方式指定E的实际类型
        public static<E> E elemOf(E[] objs,int index){
            return objs[index];
        }

     补充:

    Utilizes

      Collections:是针对集合类的一个帮助类,提供了操作集合的工具方法:一系列静态方法实现对各种集合的搜索、排序、线程

            安全化等操作。

      Arrays:针对数组的一个帮助类,提供了操作arrays的工具方法:一系列静态方法对各种数组的搜索、排序等操作

        

  • 相关阅读:
    合并链表
    ImportError: cannot import name 'GMM' from 'sklearn.mixture'
    SyntaxError: invalid character in identifier
    在 jupyter notebook 中插入图片
    Atom 换行后删除前面空格,需要按2/4次退格键
    win10输入法InpuMode默认显示中文
    Visual Studio(WindowsSDK.targets(46,5): error MSB8036: 找不到 Windows SDK 版本8.1)
    atom修改注释的字体,字号,颜色
    '__int64' has not been declared
    VMware 打开虚拟机库
  • 原文地址:https://www.cnblogs.com/wengbm/p/8087731.html
Copyright © 2011-2022 走看看