21.双列集合HashMap

1. HashMap特点

在这里插入图片描述
是无序的: 不能保证 存储 和取出的元素顺序一致。

2.HashMap底层逻辑

在这里插入图片描述

在这里插入图片描述

3. 值位置存储自定义对象

// keep statistics for each client
public class Stats{
	public int clientNum;
	public static int nextNum = 0;
	public double oneWayDelay;
	public boolean delayReady = false;
	public HashSet<Integer> prevPose = new HashSet<>();
	public HashMap<Integer, Long> videoSendTime = new HashMap<>(); 
    public HashMap<Integer, Long> videoACKTime = new HashMap<>(); 
    public HashMap<Integer, Integer> videoSizeSlot = new HashMap<>();
    public HashMap<Integer, Integer> videoQualitySlot = new HashMap<>();
    public ArrayList<Integer> videoACKReport = new ArrayList<Integer>(); 
    public ArrayList<Long> timeACKReport = new ArrayList<Long>(); 
    
    // related to the rate control part
    public int curQuality = 1;
    public float estThroughput = 0; // unit: MB/s
    public float aveQuality = 0;
    public float varQuality = 0;
    public float expFactor = 0.25f;
    public int polyDegree = 5;
    PolynomialCurveFitter fitter = PolynomialCurveFitter.create(polyDegree);
    public WeightedObservedPoints obs = new WeightedObservedPoints();
    public double[] delayFitParams = new double[polyDegree];

    public long calDelayStartTime;
    public long calDelayEndTime;

    public Stats(){
    	clientNum = nextNum;
    }
    
    public void fitDelay(float rate, float newDelay) {
    	obs.add(rate, newDelay);
    	delayFitParams = fitter.fit(obs.toList());
    }
    
    public float predictDelay(float rate) {
    	double result = 0;
    	for(int i=0;i<polyDegree;i++) {
    		result += delayFitParams[i] * Math.pow(rate, i); 
    	}
    	return (float) result;
    }
    
}
public class Utils {

	// locate the statistics for each client by IP 
    public static HashMap<String, Stats> clientStats = new HashMap<>(); 
}
public class JavaServer {
    
	public static void main(String[] args) {

	    final int MovePort = 8848;
        final int FuncPort = 8080;
        final int RTSPPort = 8088;
        
        ServerThread moveServerThread = new ServerThread("Move Server thread", MovePort, 1);
        moveServerThread.start();
        
        ServerThread funcServerThread = new ServerThread("ACK Server thread", FuncPort, 2);
        funcServerThread.start();

        ServerThread rtspServerThread = new ServerThread("RTSP Server thread", RTSPPort, 0);
        rtspServerThread.start();
	}

    public static class ServerThread extends Thread {
        private int PORT;
        private int Type;

        public ServerThread(String name, int port, int type){
        	super(name);
            PORT = port;
            Type = type; // 1, movement server; 2, ACK server
        }

        @Override
        public void run(){
            try (ServerSocket serverSocket = new ServerSocket(PORT)) {
             
                while (true) {
                    Socket socket = serverSocket.accept();
                    if (socket == null) {
                    	System.out.println(Thread.currentThread().getName()+" accept socket failed.");
                    	break;
                    }
                    System.out.println(Thread.currentThread().getName()+" Receive connection from: "+socket.getInetAddress());
                    // at the initialization, receive internal IP address from client
                    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    
                    String clientAddr = reader.readLine();
                    System.out.println(Thread.currentThread().getName()+" Receive IP from: "+clientAddr);

                    if (Type == 0) {
                    	// start the RTSP thread
                    	if (!Utils.clientStats.containsKey(clientAddr)) {
	                        Utils.clientStats.put(clientAddr,new Stats());
	        	            Stats.nextNum++;
                    	}
        	            new RTPThread("RTP thread "+clientAddr,socket, Stats.nextNum, clientAddr, reader).start();  
                    }
                    
                    if (Type == 1) {
                    	Utils.teacherAddr = clientAddr;
                    	PredictThread predThread = new PredictThread("Prediction Thread",socket,reader);
                        predThread.start();
                    }
                    
                    else if (Type == 2) {
                    	// wait for the statistic object initialization of the client
                    	while(!Utils.clientStats.containsKey(clientAddr)){
                            try{
                                Thread.sleep(1);
                            }
                            catch (InterruptedException e){
                            	e.printStackTrace();
                            }
                        }
                    	// start the functional thread
	                    FuncThread funcThread = new FuncThread("Functionalthread "+clientAddr,socket,clientAddr,reader);
	                    funcThread.start();
                    }
                }
            } catch (IOException ex) {
                System.out.println(Thread.currentThread().getName()+" exception: " + ex.getMessage());
                ex.printStackTrace();
            }
        }
    }
}

 //遍历
for (String IP : Utils.clientStats.keySet()) {

	IPs[cnt] = IP;
	Stats statistics = Utils.clientStats.get(IP);
	bandwidth_clients[cnt] = statistics.estThroughput;
	d_qualities[cnt] = 1;
	v_qualities[cnt] = 1;
	cnt++;
}

4.键位置存储自定义对象

HashMap的键位置如果存储的是自定义对象,需要重写hashCode 和 equals方法

5.利用Map集合进行统计

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值