精通Java學習之路(四)

来源:https://www.cnblogs.com/hepingan/archive/2023/08/24/17653169.html
-Advertisement-
Play Games

—併發包— 大型企業開發才用,我Java學得差不多以後再來學,主要是有點難,沒學泛型與集合… 練手的ConcurrentHashMap: import java.util.HashMap;import java.util.Hashtable;import java.util.concurrent.C ...


—併發包—

大型企業開發才用,我Java學得差不多以後再來學,主要是有點難,沒學泛型與集合…

練手的ConcurrentHashMap:

import java.util.HashMap;
import java.util.Hashtable;
import java.util.concurrent.ConcurrentHashMap;

public class bingfa {
public static HashMap<String,String> maps=new HashMap<>();
// public static Map<String,String> maps=new Hashtable<>();

public static void main(String[] args) {
Runnable r1=new MyRunnable();
Thread t1=new Thread(r1,"線程1");
Thread t2=new Thread(r1,"線程2");

t1.start();
t2.start();
try {
t1.join();//讓t1跑完,主線程不能競爭t1的CPU
t2.join();//讓t2跑完,主線程不能競爭t2的CPU
} catch (InterruptedException e) {
throw new RuntimeException(e);
}System.out.println("元素個數:"+maps.size());
}
static class MyRunnable implements Runnable{
@Override
public void run() {
for(int i=1;i<=500000;i++){
bingfa.maps.put(Thread.currentThread().getName()+i,Thread.currentThread().getName()+i);
}
}}
}

—Map集合—

Map集合特點:無序性,不重覆性(後面重覆的鍵對應的元素會覆蓋前面的整個元素),無索引的,對值無要求都可以為null。一個元素的組成為鍵和值,一個鍵對應一個值,就像地圖上一個地方對應一個地點名字,所以叫Map集合。

HashMap:無序,不重覆,無索引,值不做要求。經典的用得最多。

LinkedHashMap:有序,不重覆,無索引,值不做要求。

TreeMap:浮點型的大小比較按照自己的排序,不重覆,無索引,值不做要求。

Map的創建:Map<引用數據類型,引用數據類型> map=new HashMap/LinkedHashMap/TreeMap<>();ps:引用數據類型可以是其他類名的哦~

添加數據:map.put(xx,xx);

刪除特定元素:map.remove(鍵);刪除全部元素就直接map.clear();

判斷是否包含某個鍵:map.containsKey(鍵);

判斷是否包含某個值:map.containsValue(值);

將maps2的所有元素全部仍到maps中:map.putAll(maps2);

獲取對應鍵的值:map.get(鍵);

Set<String> keys=map.keySet();//獲取全部鍵的集合,Set無序不重覆
for (String key: keys){
System.out.println(key);
}
Collection<Integer> values=map.values();//因為值可能有重覆,所以用Collection集合
for (Integer value: values){
System.out.println(value+”,”+map.size());
}

遍歷方法:

遍歷方式1:鍵找值(key的值為String,value的類型為Integer):for(String key:maps.keySet()){Integer value =maps.get(key);System.out.println(key+”=”+value)};

遍歷方式2:鍵值對方式獲取:相較於鍵找值更加面向對象,但代碼複雜,它是把鍵值對當成一個整體遍歷,也就是直接使用foreac遍歷:for(被遍歷集合的元素類型 變數 :集合名稱){…};有點像python的字典,創建方法:Set<Map.Entry<String,Integer>> xxx=maps.entrySet();

遍歷方式3(最簡單的):k,v只是個隨便定義的變數,名字亂取都行

maps.forEach((k,v) ->{
System.out.println(k+”–>”+v);
});

—-網路通信—-

C/S結構的軟體開發:客戶需要下載客戶端,一更新客戶端也要更新。
B/S結構軟體開發:類似於網上開發,客服不用下客服端。
網路通信三要素:協議,IP地址,埠號。
協議就是電腦網路客戶端與服務端通信必須事先約定和彼此遵守的通信規則,一般有HTTP,FTP,TCP,UDP,SSH,SMTP.
IP地址:Internet Protocol Address互聯網協議地址。有IPv4和IPv6.

IPv4:4個位元組,32位組成
埠:如果說IP相當於一個酒店,埠就相當於酒店的房間號。埠取值範圍:0~65535.比如瀏覽器的埠號就是80。
查看自己的ip:在cmd命令板輸入ipconfig,嘗試連接:ping ip地址或網站功能變數名稱。
獲取本地地址對象:(如果是公網IP就會優先輸出公網IP,沒有就是本地IP)
Inet4Address ip = (Inet4Address) Inet4Address.getLocalHost();
        System.out.println(ip.getHostName());
        System.out.println(ip.getHostAddress());
獲取網站的ip地址:InetAddress ip2=InetAddress.getByName(“www.hepingan.top”);
        System.out.println(ip2.getHostName());
        System.out.println(ip2.getHostAddress());
測試連接:InetAddress ip3=InetAddress.getByName(“www.baidu.com”);
        System.out.println(ip3.isReachable(5000));//ping
相當於ping xxx,在規定時間內連接,成功輸出true,失敗false

UDP通信:

與服務端傳輸信息不需要進行交手,所以不怎麼安全,但可以用作開發實時通訊等。
創建集裝箱的參數:DatagramPacket packet =new DatagramPacket(數據包,數據包的長度,【IP地址】,【埠號】);發送的客戶端要寫【】內的,接受的服務端不用寫。
創建接收和發送數據的碼頭:DataSocket socket =new DataSocket();
(客戶端)發送數據:socket.send(packet);
(服務端)接收數據:socket.receive(packet);
關閉碼頭:socket.close();

TCP通信(重點):

一般web網站都是用的TCP/IP協議。
TCP/IP協議 ==> Transfer Control Protocol ==> 傳輸控制協議
TCP/IP協議的特點
* 面向連接的協議
* 只能由客戶端主動發送數據給伺服器端,伺服器端接收到數據之後,可以給客戶端響應數據。
* 通過三次握手建立連接,連接成功形成數據傳輸通道。
* 通過四次揮手斷開連接
* 基於IO流進行數據傳輸
* 傳輸數據大小沒有限制
* 因為面向連接的協議,速度慢,但是是可靠的協議。

客戶端的開發流程:
1.客戶端要請求於服務端的socket管道連接。
2.從socket通信管道中得到一個位元組輸出流
3.通過位元組輸出流給服務端寫出數據。
服務端的開發流程:
1.註冊埠。
2.接收客戶端的Socket管道連接。
3.從socket通信管道中得到一個位元組輸入流。
4.從位元組輸入流中讀取客戶端發來的數據。
小結:
1.客戶端用Socket連接服務端。Socket socket=new Socket(ip,port)
2.服務端用ServerSocket註冊埠,接收客戶端的Socket連接。ServerSocket ss=new ServerSocket(port);
3.通信是很嚴格的,對方怎麼發,你就應該怎麼收,對方發多少你就只能收多少。
4.實現的面向連接的socket端到端的通信管道,一方如果出現對象,另一方會出現異常!

2023最新IO傳輸方法:使用DataI/OStream數據輸入輸出流進行傳輸,對DataStream對象使用writeUTF和readUTF進行就收發送和讀寫。就不用用byte了

總的方法就是客戶端先創建Socket管道用於數據的傳輸管道,需要輸入傳輸的IP地址和埠,再創建OutputStream對象從Socket管道中得到一個位元組輸出流,然後用DataOutputStream包裝成高級的數據輸出流,最後用writeUTF(msg)就可以發送消息了。服務端先註冊一個埠號:ServerSocket ss=new ServerSocket(埠號),然後等待連接管道Socket socket =ss.accept(),再創建InputStream並使用DataInputStream打包成數據輸入流,最後創建個String類型變數使用readUTF()讀寫數據就行了。

volatile類型變數用於解決多個線程訪問共用變數是會出現一個線程修改變數值後其他線程看不到最新的線程值。

TCP通信實現多個客服端和服務端發消息(未使用線程池的):學完網路通信能寫出下麵的就可以畢業了~

客戶端:

package new_TCPstudy;

import java.io.DataOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Scanner;

public class Client {
public static void main(String[] args) throws IOException {
System.out.println("客服端啟動");
Socket socket=new Socket(InetAddress.getLocalHost(),9999);
//從socket管道中得到一個位元組輸出流
OutputStream OutputStream=socket.getOutputStream();
//包裝成高級的數據輸出流
DataOutputStream dataOutputStream=new DataOutputStream(OutputStream);
Scanner scanner=new Scanner(System.in);
while (true){
System.out.println("請說:");
String msg=scanner.nextLine();
//輸入exit退出客戶端
if("exit".equals(msg)){
System.out.println("退出客服端...");
dataOutputStream.close();
socket.close();
break;
}
dataOutputStream.writeUTF(msg);
dataOutputStream.flush();
}
}
}

服務端:

package new_TCPstudy;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
public static void main(String[] args) throws IOException {
System.out.println("服務端,啟動!");
//為服務端註冊埠
ServerSocket ss=new ServerSocket(9999);
//創建管道等待接收連接
while (true){
Socket socket=ss.accept();
System.out.println(socket.getInputStream()+"上線了~");
new ServerThread(socket).start();
}
}
public static class ServerThread extends Thread{
private Socket socket;
public ServerThread(Socket socket){
this.socket=socket;
}
@Override
public void run() {
try {
InputStream inputStream=socket.getInputStream();
//包裝成高級的數據輸入流
DataInputStream dataInputStream=new DataInputStream(inputStream);
while (true){
String msg=dataInputStream.readUTF();
System.out.println("收到來自"+socket.getRemoteSocketAddress()+"的消息:"+msg);
}
}catch (Exception e){
System.out.println(socket.getRemoteSocketAddress()+"下線了");
}
}
}
}

Map集合學習時的代碼:

import java.sql.Connection;
import java.util.*;
public class MapDemo {
public static void main(String[] args) {
Map<String ,Integer> maps=new HashMap<>();
Map<String,Integer> maps2=new LinkedHashMap<>();
Map<String,Integer> maps3=new TreeMap<>();
System.out.println(maps2.isEmpty());//判斷是否為空集合,是則返回true,反之
maps.put("food",5);
maps.clear();//清空
maps2.put("long",15);
maps.put("doll",1);
maps.put("Huawei",2);
maps.put("doll",10);//後面的把前面的覆蓋了
maps.put("iphone",2);
maps.put(null,null);
maps.put("people",8);
maps.putAll(maps2);//maps2的所有元素全部仍到maps
maps.remove("people");//刪除特定元素
Integer value1 =maps.get(null);//獲取null的值

System.out.println(maps);
System.out.println(maps.get("iphone")+","+value1);//輸出iphone的值和 null的值

Set<String> keys=maps.keySet();//獲取全部鍵的集合,Set無序不重覆
for (String key: keys){
Integer value=maps.get(key);//獲取對應鍵的值
System.out.println(key+"="+value);
}
Collection<Integer> values=maps.values();//因為值可能有重覆,所以用Collection集合
for (Integer value: values){
for(String key:maps.keySet()){
if(value==maps.get(key)){
System.out.println(value+"值的有"+key);
}
}
}
System.out.println(maps.size());// maps的大小

Set<Map.Entry<String,Integer>> entries=maps.entrySet();//鍵值對方式
System.out.println(entries);
for (Map.Entry<String, Integer> entry : entries) {
String key=entry.getKey();
Integer value=entry.getValue();
System.out.println(key+"-->"+value);
}
//最簡單的遍歷方法
maps.forEach((k,v) ->{
System.out.println(k+"-->"+v);
});
}
}

啤酒問題(遞歸思路)

import java.io.File;
import java.io.IOException;
import java.util.Scanner;
/**
* 啤酒問題:Beer: 2/bottle,4 hats can change a beer,2 empty bottle can change a beer,question:how many bottle can 10 rmb drink?
*/
public class bbb {
public static int totalNumber;
public static int lastBottles;
public static int lastHats;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("你帶了多少錢:");
buy(sc.nextInt());
System.out.println("你能喝"+totalNumber+"瓶");
System.out.println("剩餘瓶子數:"+lastBottles);
System.out.println("剩餘蓋子數:"+lastHats);
}
public static void buy(int money){
totalNumber+=money/2;
lastBottles+=money/2;
lastHats+=money/2;
int newNumber=0;
if(lastBottles>=2){
newNumber+=lastBottles/2;
lastBottles=lastBottles%2;
}
if(lastHats>=4){
newNumber+=lastHats/4;
lastHats=lastHats%4;
}
if (newNumber>0){
buy(newNumber*2);
}
}
}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • # 本文簡介 帶尬猴! 你是否在使用 `Fabric.js` 時希望能在選中元素後自定義元素樣式或選框(控制角和輔助線)的樣式? ![file](https://img2023.cnblogs.com/other/2700980/202308/2700980-20230823211856528-21 ...
  • > 優雅解決方案在最下麵,小伙伴們兒可以直接前往 😊 > # 背景 在vue3+vite2項目中,我們有時候想要動態綁定資源,比如像下麵的代碼這樣: ```html ``` 實際效果是這樣: ![](https://img2023.cnblogs.com/blog/3153981/202308/3 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 前言 隨著JavaScript在現代軟體開發中的日益重要地位,Node.js生態系統中的npm成為了不可或缺的工具。在npm管理依賴的過程中,package-lock.json文件的作用日益凸顯。本文將深入探討為什麼要使用package- ...
  • 今天在寫一個選擇器的時候出現一個問題 這個功能需求是:通過選擇器選擇不同的選項,點擊查詢按鈕發送請求,並將響應結果放到一個div中用v-if控制是否顯示。 看似簡單的一個功能,卻出現一個很搞笑的bug。在我選擇一個選項點擊查詢,本應該顯示結果的div沒有顯示出來,而在選擇一個其他選項,不需要點擊查詢 ...
  • ##### 13 CSS 的position屬性 就像photoshop中的圖層功能會把一整張圖片分層一個個圖層一樣,網頁佈局中的每一個元素也可以看成是一個個類似圖層的層模型。層佈局模型就是把網頁中的每一個元素看成是一層一層的,然後通過定位屬性position對元素進行定位擺放,最終實現網頁的佈局。 ...
  • ##### 12 CSS 的float屬性 - 流動佈局 流動模型(Flow),即文檔流,瀏覽器打開HTML網頁時,從上往下,從左往右,逐一載入。 在正常情況下,HTML元素都會根據文檔流來分佈網頁內容的。 文檔流有2大特征: ① 塊狀元素會隨著瀏覽器讀取文檔的順序,自上而下垂直分佈,一行一個的形式 ...
  • 伴隨物流行業的迅猛發展,一體化供應鏈模式的落地,對系統吞吐、系統穩定發出巨大挑戰,庫存作為供應鏈的重中之重表現更為明顯。 ...
  • ### 歡迎訪問我的GitHub > 這裡分類和彙總了欣宸的全部原創(含配套源碼):[https://github.com/zq2599/blog_demos](https://github.com/zq2599/blog_demos) ### 本篇概覽 - 本篇是《java與es8實戰》系列的第二 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...