雙端java
Ⅰ 集合java代碼如何實現
java集合 Collection為父介面,包括list、set、map等常用。
list:有序,可重復
set:無序,不可重復
map:以鍵值對方式存在的,鍵唯一,值唯一
下面列舉一些開發中常用的:
1.List相關
List books = new ArrayList();
//向books集合中添加三個元素
books.add(new String("輕量級Java EE企業應用實戰"));
books.add(new String("瘋狂Java講義"));
books.add(new String("瘋狂Android講義"));
LinkedList books = new LinkedList();
//將字元串元素加入隊列的尾部(雙端隊列)
books.offer("瘋狂Java講義");
//將一個字元串元素加入棧的頂部(雙端隊列)
books.push("輕量級Java EE企業應用實戰");
2.set相關
HashSet books = new HashSet();
//分別向books集合中添加兩個A對象,兩個B對象,兩個C對象
books.add(new A());
books.add(new A());
LinkedHashSet books = new LinkedHashSet();
books.add("Java");
books.add("LittleHann");
System.out.println(books);
TreeSet nums = new TreeSet();
//向TreeSet中添加四個Integer對象
nums.add(5);
nums.add(2);
nums.add(10);
nums.add(-9);
3.map相關
Map map = new HashMap();
map.put("key1","lisi1");
map.put("key2","lisi2");
map.put("key3","lisi3");
map.put("key4","lisi4");
Hashtable ht = new Hashtable();
ht.put(new A(60000) , "瘋狂Java講義");
ht.put(new A(87563) , "輕量級Java EE企業應用實戰");
ht.put(new A(1232) , new B());
LinkedHashMap scores = new LinkedHashMap();
scores.put("語文" , 80);
scores.put("英文" , 82);
scores.put("數學" , 76);
TreeMap tm = new TreeMap();
tm.put(new R(3) , "輕量級Java EE企業應用實戰");
tm.put(new R(-5) , "瘋狂Java講義");
tm.put(new R(9) , "瘋狂Android講義");
WeakHashMap whm = new WeakHashMap();
whm.put(new String("語文") , new String("良好"));
whm.put(new String("數學") , new String("及格"));
whm.put(new String("英文") , new String("中等"));
Ⅱ 在Java中如何實現雙向鏈表
雙向鏈表:就是有雙向指針,即雙向的鏈域。
鏈結點的結構:
┌────┬────┬────────┐
│ data │ next │ previous │
└────┴────┴────────┘
雙向鏈表不必是雙端鏈表(持有對最後一個鏈結點的引用),雙端鏈表插入時是雙向的。
有兩條鏈:一條從頭到尾,一條從尾到頭,刪除遍歷時也是雙向的。
/**
* 雙向鏈表
*/
public class DoublyLinkedList<t> {
private Link<t> head; //首結點
private Link<t> rear; //尾部指針
public DoublyLinkedList() { }
public T peekHead() {
if (head != null) {
return head.data;
}
return null;
}
public boolean isEmpty() {
return head == null;
}
public void insertFirst(T data) {// 插入 到 鏈頭
Link<t> newLink = new Link<t>(data);
if (isEmpty()) {//為空時,第1次插入的新結點為尾結點
rear = newLink;
} else {
head.previous = newLink; //舊頭結點的上結點等於新結點
}
newLink.next = head; //新結點的下結點舊頭結點
head = newLink; //賦值後,頭結點的下結點是舊頭結點,上結點null
}
public void insertLast(T data) {//在鏈尾 插入
Link<t> newLink = new Link<t>(data);
if (isEmpty()) {
head = newLink;
} else {
rear.next = newLink;
}
newLink.previous = rear;
rear = newLink; //賦值後,尾結點的上結點是舊尾結點,下結點null
}
public T deleteHead() {//刪除 鏈頭
if (isEmpty()) return null;
Link<t> temp = head;
head = head.next; //變更首結點,為下一結點
if (head != null) {
head.previous = null;
} else {
rear = null;
}
return temp.data;
}
public T deleteRear() {//刪除 鏈尾
if (isEmpty()) return null;
Link<t> temp = rear;
rear = rear.previous; //變更尾結點,為上一結點
if (rear != null) {
rear.next = null;
} else {
head = null;
}
return temp.data;
}
public T find(T t) {//從頭到尾find
if (isEmpty()) {
return null;
}
Link<t> find = head;
while (find != null) {
if (!find.data.equals(t)) {
find = find.next;
} else {
break;
}
}
if (find == null) {
return null;
}
return find.data;
}
public T delete(T t) {
if (isEmpty()) {
return null;
}
Link<t> current = head;
while (!current.data.equals(t)) {
current = current.next;
if (current == null) {
return null;
}
}
if (current == head) {
head = head.next;
if (head != null) {
head.previous = null;
}
} else if (current == rear) {
rear = rear.previous;
if (rear != null) {
rear.next = null;
}
} else {
//中間的非兩端的結點,要移除current
current.next.previous = current.previous;
current.previous.next = current.next;
}
return current.data;
}
public boolean insertAfter(T key, T data) {//插入在key之後, key不存在return false
if (isEmpty()) {
return false;
}
Link<t> current = head;
while (!current.data.equals(key)) {
current = current.next;
if (current == null) {
return false;
}
}
Link<t> newLink = new Link<t>(data);
if (current == rear) {
rear = newLink;
} else {
newLink.next = current.next;
current.next.previous = newLink;
}
current.next = newLink;
newLink.previous = current;
return true;
}
public void displayList4Head() {//從頭開始遍歷
System.out.println("List (first-->last):");
Link<t> current = head;
while (current != null) {
current.displayLink();
current = current.next;
}
}
public void displayList4Rear() {//從尾開始遍歷
System.out.println("List (last-->first):");
Link<t> current = rear;
while (current != null) {
current.displayLink();
current = current.previous;
}
}
class Link<t> {//鏈結點
T data; //數據域
Link<t> next; //後繼指針,結點 鏈域
Link<t> previous; //前驅指針,結點 鏈域
Link(T data) {
this.data = data;
}
void displayLink() {
System.out.println("the data is " + data.toString());
}
}
public static void main(String[] args) {
DoublyLinkedList<integer> list = new DoublyLinkedList<integer>();
list.insertLast(1);
list.insertFirst(2);
list.insertLast(3);
list.insertFirst(4);
list.insertLast(5);
list.displayList4Head();
Integer deleteHead = list.deleteHead();
System.out.println("deleteHead:" + deleteHead);
list.displayList4Head();
Integer deleteRear = list.deleteRear();
System.out.println("deleteRear:" + deleteRear);
list.displayList4Rear();
System.out.println("find:" + list.find(6));
System.out.println("find:" + list.find(3));
System.out.println("delete find:" + list.delete(6));
System.out.println("delete find:" + list.delete(1));
list.displayList4Head();
System.out.println("----在指定key後插入----");
list.insertAfter(2, 8);
list.insertAfter(2, 9);
list.insertAfter(9, 10);
list.displayList4Head();
}
}
Ⅲ java雙向鏈表
public boolean putAfter(Object obj,DoublyListNode node)//有可能找不到obj,所以我返回boolean
{
DoublyListNode current = head;
while(head.obj!=obj){
current = current.next;
if(current==null)
return false;
}
if(current==tail){
node.next = null;
tail = node;
}else{
node.next = current.next;
current.next.previous = node;
}
node.previous = current;
current.next =node;
return true;
}
public DoublyListNode removeafter(Object obj){//返回了選中的節點
DoublyListNode current = head;
while(current.obj!=obj)
{
current = current.next;
if(current == null)
return null;
}
if(current==head)
head = current.next;
else
current.previous.next = current.next;
if(current == tail)
tail = current.previous;
else
current.next.previous = current.previous;
return current;
}
Ⅳ java,雙端鏈表
如果為空,第一個創建的結點也是最後一個結點,所以last也指向它。
if(isEmpty())
last=newLink;
如果不為空的話,在表頭插入,插入的結點成為第一一個結點,之前的第一結點變為第二結點,有當前新的結點指向
newLink.next=first;
first=newLink;
Ⅳ 通過Java中的Socket技術編寫能夠進行雙向通信的客戶端和伺服器,為了能夠同時進行消息的發送和接受,在服
SocketClient1.java內容如下:
package com.polyphylla.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
public class SocketClient1 {
private Socket socket;
public SocketClient1() {
try {
socket = new Socket("127.0.0.1", 2222);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* @param args
*/
public static void main(String[] args) {
new SocketClient1().startClient();
}
public void startClient() {
new Thread(new ClientReader(socket)).start();
new Thread(new ClientWriter(socket)).start();
}
}
class ClientReader implements Runnable {
private Socket socket;
public ClientReader(Socket socket) {
this.socket = socket;
}
public void run() {
BufferedReader br = getReader();
String msg = null;
try {
while ((msg = br.readLine()) != null) {
System.out.println("client:" + msg);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (br != null)
br.close();
if (socket != null)
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private BufferedReader getReader() {
try {
return new BufferedReader(new InputStreamReader(socket
.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
class ClientWriter implements Runnable {
private Socket socket;
public ClientWriter(Socket socket) {
this.socket = socket;
}
public void run() {
PrintWriter pw = getWriter();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = null;
try {
while ((str = br.readLine()) != null) {
pw.println(str);
pw.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (pw != null)
pw.close();
try {
if (socket != null)
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private PrintWriter getWriter() {
try {
return new PrintWriter(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
SocketServer1.java內容如下:
package com.polyphylla.socket;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
public class SocketServer1 {
private ServerSocket ss;
public SocketServer1() {
try {
ss = new ServerSocket(2222);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new SocketServer1().startServer();
}
public void startServer() {
try {
while (true) {
Socket s = ss.accept();
new Thread(new ServerReader(s)).start();
new Thread(new ServerWriter(s)).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
class ServerReader implements Runnable {
private Socket socket;
public ServerReader(Socket socket) {
this.socket = socket;
}
public void run() {
BufferedReader br = getReader();
String msg = null;
try {
while((msg = br.readLine()) != null) {
System.out.println("server:" + msg);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if(br != null)
br.close();
if(socket != null)
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private BufferedReader getReader() {
try {
return new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
class ServerWriter implements Runnable {
private Socket socket;
public ServerWriter(Socket socket) {
this.socket = socket;
}
public void run() {
PrintWriter pw = getWriter();
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String str = null;
try {
while((str = br.readLine()) != null) {
pw.println(str);
pw.flush();
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (pw != null)
pw.close();
try {
if (socket != null)
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private PrintWriter getWriter() {
try {
return new PrintWriter(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Ⅵ java中用socket實現客戶端與服務端雙向連接問題
//服務端程序:
importjava.io.*;
importjava.net.*;
publicclassTCPServer{
publicstaticvoidmain(String[]args)throwsIOException{
newTCPServer().init();
}
@SuppressWarnings("static-access")
privatevoidinit()throwsIOException{
@SuppressWarnings("resource")
ServerSocketserver=newServerSocket(1000);
Socketclient=null;
while(true){
try{
client=server.accept();
BufferedInputStreambis=newBufferedInputStream(client.getInputStream());
byte[]b=newbyte[1024];
intlen=0;
Stringmessage="";
while((len=bis.read(b))!=-1){
message=newString(b,0,len);
System.out.print("客戶端:"+client.getInetAddress().getLocalHost().getHostAddress()+"發來消息:"+message);
if("byte".equals(message.trim()))
client.close();
PrintWriterpw=newPrintWriter(client.getOutputStream(),true);
pw.println(message);
}
}catch(Exceptione){
System.err.println("客戶端:"+client.getInetAddress().getLocalHost().getHostAddress()+"已斷開連接!");
}
}
}
}
//客戶端程序:
importjava.io.*;
importjava.net.Socket;
{
publicstaticvoidmain(String[]args)throwsIOException{
newTCPClient().init();
}
privatevoidinit()throwsIOException{
@SuppressWarnings("resource")
finalSocketclient=newSocket("127.0.0.1",1000);
BufferedReaderin=newBufferedReader(newInputStreamReader(System.in));
Stringsend="";
while(true){
send=in.readLine();
PrintWriterout=newPrintWriter(client.getOutputStream(),true);
if(!"byte".equals(send.trim()))
out.println(send);
else{
out.println(send);
System.exit(0);
}
newThread(newTCPClient(){
@SuppressWarnings("static-access")
publicvoidrun(){
try{
BufferedInputStreambis=newBufferedInputStream(client.getInputStream());
byte[]b=newbyte[1024];
intlen=0;
while((len=bis.read(b))!=-1){
System.out.println("伺服器:"+client.getInetAddress().getLocalHost().getHostAddress()+"發來消息:"+newString(b,0,len).trim());
}
}catch(IOExceptione){
System.err.println("連接伺服器失敗!");
}
}
}).start();
}
}
publicvoidrun(){}
}
//伺服器測試結果:
客戶端:192.168.0.200發來消息:001 byte
客戶端:192.168.0.200發來消息:byte
客戶端:192.168.0.200 已斷開連接!
客戶端:192.168.0.200發來消息:adasd
客戶端:192.168.0.200 已斷開連接!
//客戶端測試結果:
---001號客戶端--
001byte
伺服器:192.168.0.200發來消息:001byte
byte //001禮貌說跟伺服器說byte
---002號客戶端--
adasd //002客戶端直接關閉程序
伺服器:192.168.0.200發來消息:adasd
Ⅶ Java:雙端隊列插入節點,關於隊列為空時插入節點的疑問
隊列為空的情況下 在首部添加新節點的時候,其實firstNode和lastNode相同都是newNode
,但是無論隊列是否為空 方法的最後都會設置firstNode=newNode, 所以為空的時候會設置lastNode=newNode; 在尾部添加新節點的道理也是這樣;
Ⅷ java Nio讀寫為什麼是雙向
作者:美團技術團隊
鏈接:https://zhuanlan.hu.com/p/23488863
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請註明出處。
NIO(Non-blocking I/O,在Java領域,也稱為New I/O),是一種同步非阻塞的I/O模型,也是I/O多路復用的基礎,已經被越來越多地應用到大型應用伺服器,成為解決高並發與大量連接、I/O處理問題的有效方式。
那麼NIO的本質是什麼樣的呢?它是怎樣與事件模型結合來解放線程、提高系統吞吐的呢?
本文會從傳統的阻塞I/O和線程池模型面臨的問題講起,然後對比幾種常見I/O模型,一步步分析NIO怎麼利用事件模型處理I/O,解決線程池瓶頸處理海量連接,包括利用面向事件的方式編寫服務端/客戶端程序。最後延展到一些高級主題,如Reactor與Proactor模型的對比、Selector的喚醒、Buffer的選擇等。
註:本文的代碼都是偽代碼,主要是為了示意,不可用於生產環境。
傳統BIO模型分析
讓我們先回憶一下傳統的伺服器端同步阻塞I/O處理(也就是BIO,Blocking I/O)的經典編程模型:
{
ExecutorService executor = Excutors.newFixedThreadPollExecutor(100);//線程池
ServerSocket serverSocket = new ServerSocket();
serverSocket.bind(8088);
while(!Thread.currentThread.isInturrupted()){//主線程死循環等待新連接到來
Socket socket = serverSocket.accept();
executor.submit(new ConnectIOnHandler(socket));//為新的連接創建新的線程
}
class ConnectIOnHandler extends Thread{
private Socket socket;
public ConnectIOnHandler(Socket socket){
this.socket = socket;
}
public void run(){
while(!Thread.currentThread.isInturrupted()&&!socket.isClosed()){死循環處理讀寫事件
String someThing = socket.read()....//讀取數據
if(someThing!=null){
......//處理數據
socket.write()....//寫數據
}
}
}
}
這是一個經典的每連接每線程的模型,之所以使用多線程,主要原因在於socket.accept()、socket.read()、socket.write()三個主要函數都是同步阻塞的,當一個連接在處理I/O的時候,系統是阻塞的,如果是單線程的話必然就掛死在那裡;但CPU是被釋放出來的,開啟多線程,就可以讓CPU去處理更多的事情。其實這也是所有使用多線程的本質:
利用多核。
當I/O阻塞系統,但CPU空閑的時候,可以利用多線程使用CPU資源。
線程的創建和銷毀成本很高,在Linux這樣的操作系統中,線程本質上就是一個進程。創建和銷毀都是重量級的系統函數。
線程本身佔用較大內存,像Java的線程棧,一般至少分配512K~1M的空間,如果系統中的線程數過千,恐怕整個JVM的內存都會被吃掉一半。
線程的切換成本是很高的。操作系統發生線程切換的時候,需要保留線程的上下文,然後執行系統調用。如果線程數過高,可能執行線程切換的時間甚至會大於線程執行的時間,這時候帶來的表現往往是系統load偏高、CPU sy使用率特別高(超過20%以上),導致系統幾乎陷入不可用的狀態。
容易造成鋸齒狀的系統負載。因為系統負載是用活動線程數或CPU核心數,一旦線程數量高但外部網路環境不是很穩定,就很容易造成大量請求的結果同時返回,激活大量阻塞線程從而使系統負載壓力過大。
現在的多線程一般都使用線程池,可以讓線程的創建和回收成本相對較低。在活動連接數不是特別高(小於單機1000)的情況下,這種模型是比較不錯的,可以讓每一個連接專注於自己的I/O並且編程模型簡單,也不用過多考慮系統的過載、限流等問題。線程池本身就是一個天然的漏斗,可以緩沖一些系統處理不了的連接或請求。
不過,這個模型最本質的問題在於,嚴重依賴於線程。但線程是很"貴"的資源,主要表現在:
所以,當面對十萬甚至百萬級連接的時候,傳統的BIO模型是無能為力的。隨著移動端應用的興起和各種網路游戲的盛行,百萬級長連接日趨普遍,此時,必然需要一種更高效的I/O處理模型。
NIO是怎麼工作的
很多剛接觸NIO的人,第一眼看到的就是Java相對晦澀的API,比如:Channel,Selector,Socket什麼的;然後就是一坨上百行的代碼來演示NIO的服務端Demo……瞬間頭大有沒有?
我們不管這些,拋開現象看本質,先分析下NIO是怎麼工作的。
常見I/O模型對比
所有的系統I/O都分為兩個階段:等待就緒和操作。舉例來說,讀函數,分為等待系統可讀和真正的讀;同理,寫函數分為等待網卡可以寫和真正的寫。
需要說明的是等待就緒的阻塞是不使用CPU的,是在「空等」;而真正的讀寫操作的阻塞是使用CPU的,真正在"幹活",而且這個過程非常快,屬於memory ,帶寬通常在1GB/s級別以上,可以理解為基本不耗時。
下圖是幾種常見I/O模型的對比:
以上都是小編收集了大神的靈葯,喜歡的拿走吧!喜歡小編就輕輕關注一下吧!
Ⅸ JAVA怎麼實現雙向循環鏈表 如果用LINKEDLIST,我只知道他有hasnext,next方法,那怎麼取前一個節點的內容
LinkedList雖然介面是單項的,但內部實現是雙向的。
如下方法可以使用:
Iterator<E> descendingIterator() 返回以逆向順序在此雙端隊列的元素上進行迭代的迭代器。
for(Object o : list.descendingIterator()){ ... }
Ⅹ 用JAVA語言,編寫一個鏈表類(雙向鏈表),實現插入,刪除,查找操作。新手,要俗易懂些,最好自己調適通過。急
定義介面:
//Deque.java
package dsa; //根據自己的程序位置不同
public interface Deque {
public int getSize();//返回隊列中元素數目
public boolean isEmpty();//判斷隊列是否為空
public Object first() throws ExceptionQueueEmpty;//取首元素(但不刪除)
public Object last() throws ExceptionQueueEmpty;//取末元素(但不刪除)
public void insertFirst(Object obj);//將新元素作為首元素插入
public void insertLast(Object obj);//將新元素作為末元素插入
public Object removeFirst() throws ExceptionQueueEmpty;//刪除首元素
public Object removeLast() throws ExceptionQueueEmpty;//刪除末元素
public void Traversal();//遍歷
}
雙向鏈表實現:
//Deque_DLNode.java
/*
* 基於雙向鏈表實現雙端隊列結構
*/
package dsa;
public class Deque_DLNode implements Deque {
protected DLNode header;//指向頭節點(哨兵)
protected DLNode trailer;//指向尾節點(哨兵)
protected int size;//隊列中元素的數目
//構造函數
public Deque_DLNode() {
header = new DLNode();
trailer = new DLNode();
header.setNext(trailer);
trailer.setPrev(header);
size = 0;
}
//返回隊列中元素數目
public int getSize()
{ return size; }
//判斷隊列是否為空
public boolean isEmpty()
{ return (0 == size) ? true : false; }
//取首元素(但不刪除)
public Object first() throws ExceptionQueueEmpty {
if (isEmpty())
throw new ExceptionQueueEmpty("意外:雙端隊列為空");
return header.getNext().getElem();
}
//取末元素(但不刪除)
public Object last() throws ExceptionQueueEmpty {
if (isEmpty())
throw new ExceptionQueueEmpty("意外:雙端隊列為空");
return trailer.getPrev().getElem();
}
//在隊列前端插入新節點
public void insertFirst(Object obj) {
DLNode second = header.getNext();
DLNode first = new DLNode(obj, header, second);
second.setPrev(first);
header.setNext(first);
size++;
}
//在隊列後端插入新節點
public void insertLast(Object obj) {
DLNode second = trailer.getPrev();
DLNode first = new DLNode(obj, second, trailer);
second.setNext(first);
trailer.setPrev(first);
size++;
}
//刪除首節點
public Object removeFirst() throws ExceptionQueueEmpty {
if (isEmpty())
throw new ExceptionQueueEmpty("意外:雙端隊列為空");
DLNode first = header.getNext();
DLNode second = first.getNext();
Object obj = first.getElem();
header.setNext(second);
second.setPrev(header);
size--;
return(obj);
}
//刪除末節點
public Object removeLast() throws ExceptionQueueEmpty {
if (isEmpty())
throw new ExceptionQueueEmpty("意外:雙端隊列為空");
DLNode first = trailer.getPrev();
DLNode second = first.getPrev();
Object obj = first.getElem();
trailer.setPrev(second);
second.setNext(trailer);
size--;
return(obj);
}
//遍歷
public void Traversal() {
DLNode p = header.getNext();
while (p != trailer) {
System.out.print(p.getElem()+" ");
p = p.getNext();
}
System.out.println();
}
}