JavaSE高级篇学习笔记

基本数据类型的封装类
1.byte Byte
char Character
short Short
int Integer
long Long
folat Float
double Double
boolean Boolean
2.自动装箱与拆箱
装箱:把基本数据类型转化为封装类型
拆箱:把封装类型转化为基本数据类型
拆箱示例:
Integer i1 = new Integer(10);
int i2=i1;
装箱示例:
int i3=9;

Integer i4=i3;

Object类介绍

1.Object类的常用方法
在java中所有的类都继承自Object类。

1、一个类的实例化对象,要想使用使用clone()方法,就必须让这个类实现Cloneable接口,然后重写clone()方法。

2、System.gc();//建议虚拟机执行垃圾回收,但不保证执行,也不保证回收所有垃圾。

    3、finalize()和gc()这两个方法我们不要试图去控制,他们是由Java虚拟机控制的,我们只有建议gc()去执行finalize(),但具体是否执行,只有Java虚拟机才知道。因为这是由Java虚拟机的算法决定的。

Math类 

Math类里面都是静态方法。

1、Math类介绍:
    double  d=Math.celi(2.98);
    System.out.println(d);
    输出结果是3 (向上取整)

    d=Math.floor(2.98);
    System.out.println(d);      
    输出结果是2 (向下取整)

    Math.Radom() [0,1)
2、猜数字小游戏

猜数字小程序优化,增加次数限制的功能。

StringBuffer类

1、StringBuffer类简介
String容量是不可变的,每次使用String时候都产生一个对象,所以可以产生大量的垃圾。而StringBuffer类容量是可变的,它是带缓存的。

    StringBuffer sb =new StringBuffer();
    System.out.println(sb.capacity());

    StringBuffer sb2=new StringBuffer("abcd");
    System.out.println(sb2.capacity());

    StringBuffer sb3=new StringBuffer(100);
    System.out.println(sb3.capacity());

2、StringBuffer类的方法

线程安全的。

Date类

1、Data类

2、格式化时间类DateFormate类

它是个抽象类,不能直接通过构造方法new出对象

可以通过以下两种方式间接获取:

//通过抽象类的静态方法获取实例
DateFormat df1=DateFormat.getInstance();
//通过new 子类获得实例
DateFormat df2=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");

示例:
public class TestDateFormate {

public static void main(String[] args) {
    Date dt=new Date();

    //通过抽象类的静态方法获取实例
    DateFormat df1=DateFormat.getInstance();
    //通过new 子类获得实例
    DateFormat df2=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    DateFormat df3=new SimpleDateFormat("yyyy年MM月dd号 hh点mm分ss秒");
    DateFormat df4=new SimpleDateFormat("yyyy-MM-dd");

    System.out.println(dt);

    System.out.println("1.通过抽象类的静态方法获取实例\n"  +df1.format(dt));

    System.out.println("2.yyyy-MM-dd hh:mm:ss\n"  +df2.format(dt));

    System.out.println("3.yyyy年MM月dd号 hh点mm分ss秒\n"  +df3.format(dt));

    System.out.println("4.yyyy-MM-dd\n"  +df4.format(dt));
}

}

    输出结果:
    Sat Aug 20 11:15:31 CST 2016
    1.通过抽象类的静态方法获取实例
    16-8-20 上午11:15
    2.yyyy-MM-dd hh:mm:ss
    2016-08-20 11:15:31
    3.yyyy年MM月dd号 hh点mm分ss秒
    2016年08月20号 11点15分31秒
    4.yyyy-MM-dd

2016-08-20

初识I/O流

流的概念
读入,写出。
输入流是读数据。
输出流是写数据。
输入输出的概念是针对程序来说的。程序往资源文件里输入,相对资源文件来说是资源文件再读程序。而程序的输出,就是资源文件在返回请求,写数据给程序。
1、字节流
用于以字节为单位的输入输出。只要是处理字节或者二进制的各种输入输出。一般是用于处理图像,声音等(文件)。
InputStream是所有文字输入流的祖先类。
OutputStream是所有字节输出流的祖先类。

2、字符流
以字符为基本处理的单位,主要用于处理字符或者是文本类型。一般用作处理文本的读取存储以及与网络的(文本)信息的交互。
Reader 是所有字符输入流的祖先类。
Writer 是所有字符输出流的祖先类。

3、文件管理
读文件 输入流

写文件 输出流

文件字节输入流

InputStream
1.FileInputStream
因为字节流每次读取一个字节,而一个字节是无法完整的描述一个中文的。所以会出现英文正常,中文乱码的情况。

public class TestFileInputStream {
public static void main(String[] args) {
    FileInputStream fis=null;
    int i=0;
    try {
        fis=new FileInputStream("E:\\个人信息\\fuben.txt");
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    try {
        i=fis.read();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    //当i=-1时,文件到达结尾
    while(i!=-1){
        System.out.print((char)i);
        try {
            i=fis.read();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

}

文件字节输出流

FileOutputStream
public class TestFileOutputStream {
public static void main(String[] args) {
String s=”woainiwangdanwoyaonulizhaodaogoodjoobformybeau”;
FileOutputStream fos=null;
FileOutputStream fos1=null;

    File f=new File("E:\\个人信息\\f.txt");
    File f1=new File("E:\\个人信息\\f1.txt");

    if(!f.exists()){
        try {
            f.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    if(!f1.exists()){
        try {
            f1.createNewFile();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    try {
        fos=new FileOutputStream(f);
        fos1=new FileOutputStream(f1);
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    byte[] b=s.getBytes();
    try {
        fos.write(b);
        fos1.write(b, 0, s.length()/2);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally{
        try {
            if(fos!=null){
                fos.close();
            }
            if(fos1!=null){
                fos1.close();
            }

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }



}

}

字节流相关的类:字节数组输入流
ByteArrayInputStream

FileInputStream的输入源是文件

ByteArrayInputStream的输入源是字节数组

rest()重置到mark标记的位置,如果没有调用过mark方法,则重置到缓冲区ay(BateArray)的起始位置
mark(int)
public class TestByteArrayInputStream {
public static void main(String[] args) throws IOException {

    String temp="abcdefghijklmnopqrstuvwxyz";
    byte[] b=temp.getBytes();
    ByteArrayInputStream bis =new ByteArrayInputStream(b);

    for(int i=0;i<2;i++){
        int c=0;
        c=bis.read();
        while(c!=-1){
            if(i==0){
                System.out.print((char)c);
            }else{
                System.out.print(Character.
                        toUpperCase((char)c));
            }
            c=bis.read();
        }
        System.out.println();
        bis.reset();
    }

}

}


输出流字节数组

1.ByteArrayOutputStream

FileoutputStream把文件作为写入的目的地(写入到硬盘)
ByteArrayOutputStream 把字节数组作为写入的目的地(写入到内存里)

public class TestByteArrayOutputStream {
public static void main(String[] args) {
    ByteArrayOutputStream bos=new ByteArrayOutputStream();
    String temp="hello world hello everyone";
    byte[] b=temp.getBytes();

    try {
        bos.write(b);
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    System.out.println(bos.toString());
        //写入到 byte[] buf=new byte[size]

    byte[] b1=bos.toByteArray();
    for(int i=0;i<b1.length;i++){
        System.out.print((char)b1[i]);
    }
}

}

字节流相关类:缓冲输入输出字节流
1、BufferedInputStream

2、BufferedOutputStream

GBK -中文占2个字节

UTF-8中文占3个字节

测试编码方式的方法:System.out.println(System.getProperty(“file.encoding”));
结果:GBK

测试一个汉字占多少个字节的方法:System.out.println(“大家好”.getBytes().length); 结果:6 所以说一个汉字在GBK编码方式下,占2个字节。

字符流的输入祖先都:Reader

字符流相关类:字符输入流

InputStreamReader 字节流通往字符流的桥梁

public class TestInputStreamReader {
public static void main(String[] args) {

    FileInputStream fis =null;
    InputStreamReader isr=null;

    try {
        fis=new FileInputStream("E:\\个人信息\\in.txt");
        isr=new InputStreamReader(fis);

        int c=0;
        c=isr.read();

        while(c!=-1){
            System.out.print((char)c);

            c=isr.read();
        }
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }catch(IOException e){
        e.printStackTrace();
    }finally{

        try {
                if(fis!=null){
                    fis.close();
                }
                if(isr!=null){
                    isr.close();
                }

        } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

}


字符流相关类:字符输出流

字符流的输出的祖先都是:Writer

OutputStrmWriter 字符到字节的桥梁(通过编码方式进行转换)

public class TestOutputStreamWriter {
public static void main(String[] args) {

    FileOutputStream fos=null;
    OutputStreamWriter osw=null;
    String s=null;

    try {
        fos=new FileOutputStream("E://个人信息//out.txt");
        osw=new OutputStreamWriter(fos);
        s="你好,我喜欢学习新技术. i like new technology!";

        for(int i=0;i<s.length();i++){
            osw.write(s.charAt(i));
        }
        osw.flush();//手动刷新很重要
    } catch (FileNotFoundException  e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally{
        //关闭流
        if(fos!=null){
            try {
                fos.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if(osw!=null){
            try {
                osw.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }

}

}

字符流相关类:读文件类

1、FileReader

public class TestFileReader {
public static void main(String[] args) {
    FileReader fr=null;


    try {
        fr=new FileReader("E:\\个人信息\\in.txt");
        int c=0;
        c=fr.read();

        while(c!=-1){
            System.out.print((char)c);
            c=fr.read();
        }
    } catch (FileNotFoundException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally{
        if(fr!=null){
            try {
                fr.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }


}

}

字符流相关类:写文件类

1、FileWriter
public class TestFileWriter {
public static void main(String[] args) {
FileWriter fw=null;

    try {
        fw=new FileWriter("E:\\个人信息\\out.txt");
        String str="你好,we come from new world!";

        for(int i=0;i<str.length();i++){
            fw.write(str.charAt(i));

        }
        fw.flush();//最好是手动调用,从内存到文件。
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally{
        if(fw!=null){
            try {
                fw.close();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

}

对象序列化
作用:
对象持久化,比如保存到硬盘的文件。
在网络中进行传输。

1.Serializable接口

2.对象输入/输出流
ObjectInputStream
(Student)ois.readObject()
(Teacher)oos.writeObject;
ObjectOutputStream
oos.writeObject(Student);
oos.writeObject(Teacher);
写几个就要读几个,还要注意的是在读的时候注意强转类型。

3.transient关键字
被它修饰的字段是无法进行序列化的,也就是没有写进文件,所以也就无法读取。(将不需要写进文件的东西进行保护)


泛型概念

作用:提高类型的安全并能简化类型转换的过程。
1.什么是泛型
1、泛型是JDK5.0新添加的特性
2、泛型就是将类型参数化
3、提高类型的安全并能简化类型转换的过程。在泛型处理过程中,所有的类型转换都是自动和隐式的。

泛型将类型的错误提前到了编译期。

2.没有泛型的情况

数据类型转换比较复杂。
Integer i2=(Integer)g1.getObject();
String s2=(String)g2.getObject();
在转换过程中会产生不安全的因素。

泛型的基本写法

泛型就是将类型参数化
泛型处理的必须是类的类型,不能用它来处理int,long等基本类型。

多个类型参数

1.使用两个或者多个类型参数

public class TwoGen

}

泛型的类型边界

1.类型边界
public class Average {
T[] ts;
public Average(T[] obj) {
this.ts=obj;
}
public int Average(){
double sum;
for(int i=0;i

}

泛型通配符的使用

类型边界的作用:
1、可以获得类型安全。
2、可以让类型有进一步的操作能力。

1.通配符的使用
通配符 ?代表参数可以使任何的Average对象

public boolean equalsAvg(Average<?> obj){
    if(this.average()==obj.average()){
        return true;
    }else {
        return false;
    }

}

泛型方法

Gen{
}
1、泛型方法
在非泛型类中也可以有泛型方法。

2、定义泛型方法的格式:

修饰符 方法类型 <参数类型列表> 返回值类型 方法名(参数列表){

}

示例:
public static boolean have(T[] ts, T t) {

}

泛型类之间的继承

1、泛型类之间的继承

GenChildextends GenParent
定义泛型子类,声明中必须包含其父类的类型参数。即便在子类中不使用任然要在参数列表中指定它。


泛型类与非泛型类之间的继承

1、泛型类与非泛型类之间的继承
父类是泛型类,子类不是泛型类(不成立)
如果子类继承了泛型父类,则子类必须得是泛型类,并且包 父类的泛型。

父类不是泛型类,子类是泛型类,正常写就可以了,没有强制性的要求
public class GenChild<T> extends Parent

泛型继承中方法覆盖

1、方法覆盖

对于泛型类的继承来说,方法覆盖同样适用!

集合框架概述

1.什么是集合框架
java的集合框架是java.util包中提供的一系列工具,它为程序处理对象组提供了标准的方式。诞生自1.2版本。
1.2版本之前,我们如何处理对象组?
1、数组
缺点:长度固定,数组中只能存放一种类型的数据。
2、Vector、Stack、Properties
缺点:缺乏统一的操作方式。不易扩展。
1.2版本之后,诞生了集合框架
优点:性能提高了。
操作统一。Collection List Set
提高了扩展性。
集合实现了Iterator接口。

        迭代器:提供了访问接口的统一方法。

        集合存储的是一组单个的数据。
        Map存储的是一组成对的数据。

2.常用接口以及实现类介绍
常用接口 Set、List、Queue

1.Set实现类:HashSet、LinkedHashSet、TreeSet
2.List实现类:ArryList、Vector、LinkedList
3.Queue实现类:LinkedList、PriorityQueue

Collection是所有集合的父接口,不包含Map

Set继承自Collection,不允许出现相同的元素。

List 继承自Collection .以列表形式存储的集合。

集合实现类ArrayList
1.ArrayList
数组列表。它可以自动扩容。
public class TestArrayList {

public static void main(String[] args) {
    ArrayList<String> all = new ArrayList<String>();
    all.add("a");
    all.add("b");
    all.add("c");
    all.add("d");
    System.out.println("all的长度是:" + all.size());
    System.out.println("all的内容" + all);

    // 增加的方法
    System.out.println("把第一个元素设置为first");
    all.add(0, "first");
    System.out.println("all的内容" + all);
    all.add("e");

    // 修改的方法
    System.out.println("把b改为B");
    all.set(2, "B");
    System.out.println("修改后all的内容" + all);

    // 删除方法
    System.out.println("删除d元素");
    all.remove("d");
    System.out.println("删除d后all的内容" + all);

    System.out.println("删除e元素");
    all.remove(4);
    System.out.println("删除e后all的内容" + all);

    // 查询方法
    for (String s : all) {
        System.out.print(s + " ");
    }

    System.out.println();
    for (int i = 0; i < all.size(); i++) {
        System.out.print(all.get(i) + " ");
    }

    System.out.println();
    System.out.println("打印s1数组");
    // ArrayList和数组的交互
    String[] s1 = new String[all.size()];
    s1 = all.toArray(s1);
    for (String s : s1) {
        System.out.print(s + " ");
    }

    System.out.println();
    ArrayList<String> all2=new ArrayList<String>(all);
    System.out.println("打印all2的内容"+all2);


    //在构造的时候指定容量
    System.out.println();
    ArrayList<String> all3=new ArrayList<String>(3);
    all3.addAll(all);
    System.out.println("all3的内容:"+all3);

}

}


list实现类:LinkedList
public class TestLinkedList {

public static void main(String[] args) {
    LinkedList<String> lel = new LinkedList<String>();
    // add方法
    lel.add("a");
    lel.add("b");
    lel.add("c");
    lel.add("d");
    lel.add("e");
    System.out.println(lel);

    //在尾部增加元素
    lel.addLast("f");
    System.out.println(lel);

    //在头部增加元素
    lel.addFirst("first");
    System.out.println(lel);

    lel.add(7, "last");
    System.out.println(lel);

    String s=lel.poll();
    System.out.println("poll操作后获取的内容:"+s);
    System.out.println("poll操作后lel的内容:"+lel);

    s=lel.peek();
    System.out.println("peek操作后获取的内容:"+s);

    s=lel.pop();
    System.out.println("pop操作后获取的内容:"+s);
    System.out.println(lel);

    String[] ss=new String[lel.size()];
    lel.toArray(ss);
    for(String s1:ss){
        System.out.print(s1+" ");
    }

    //有参的构造方法
    LinkedList<String> lel2=new LinkedList<String>(lel);
    System.out.println();
    System.out.println(lel2);

}

}

Set实现类:HashSet

它是通过散列的机制来进行存储到哈希表。它的存取速度非常快,但是不能该保证集合的顺序,它里面没有重复的值。它存取机制是通过hashcode来取余,来快速计算出它的下标,从而找到存取位置。


实现自己的ArryList

ArrayList的容量可以动态增加
    底层数据结构是数组

增、删、改、查
   boolean add(Object obj)
   Object remove(int index)
   Object set(int index,Object obj)
   Object get(int index)

toString()

迭代器介绍
1、迭代器介绍

迭代器是用来遍历集合中的元素的,通过使用迭代器,可以将遍历与数据分离。

2、迭代器的使用
通过Iterator对象来遍历集合中的元素的对象。

public static void bianli(Iterator it) {
    while (it.hasNext()) {
        System.out.print(it.next() + " ");
    }
}

3、for-each
1、通用,适用于所有的集合
2、简便,语法格式简单
for (String s : list) {

     System.out.print(s+" ");

}

Map接口介绍与实现类HasMap

1、Map接口介绍
map(key,value)
key必须唯一,value不是必须唯一。

2、实现类HasMap

public class TestHashMap {

public static void main(String[] args) {
    HashMap<Integer, String> hm = new HashMap<Integer, String>();
    hm.put(101, "老王");
    hm.put(102, "小明");
    hm.put(103, "小花");
    hm.put(104, "小李");
    Collection<String> c = hm.values();
    Iterator<String> it = c.iterator();
    System.out.println("姓名列表");
    while (it.hasNext()) {
        System.out.print(it.next() + " ");
    }

    System.out.println();
    System.out.println("学号列表");
    Set<Integer> keys = hm.keySet();
    for (Integer i : keys) {
        System.out.print(i + " ");
    }
    System.out.println();
    System.out.println("打印完整信息");
    for (Integer key : keys) {
        System.out.print("学号:" + key + ",姓名:" + hm.get(key) + "/");
    }
}

}

Map实现类TreeMap

1、TreeMap
通过树结构来实现Map接口的。
TreeMap保证了映射按照升序顺序排列key
支持快速查找

由于TreeMap会对key进行排序的,所以我们必须保证所传的key是能够进行排序的。

如何把普通的类变成可排序的类:
实现comparable接口,重写compareTo(Object obj)方法。

List

ArrayList 查询多,增加删除比较少(底层是数组)

LinkedList 增加删除比较多,查询

如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
  如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
  要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。

  尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。

网络编程之InteAddress

主机名(域名)到 IP 地址的解析 通过使用本地机器配置信息和网络命名服务(如域名系统(Domain Name System,DNS)和网络信息服务(Network Information Service,NIS))来实现。要使用的特定命名服务默认情况下是本地机器配置的那个。对于任何主机名称,都返回其相应的 IP 地址。
反向名称解析 意味着对于任何 IP 地址,都返回与 IP 地址关联的主机。

InetAddress 类提供将主机名解析为其 IP 地址(或反之)的方法。

1、InetAddres:表示网络协议地址的类,可以用于标记网络上的硬件资源(比如主机)
public class TestInetAddress {
public static void main(String[] args) {

    try {
        InetAddress ia = InetAddress.getByName("www.baidu.com");
        System.out.println(ia);
        System.out.println("------------------------------------");
        InetAddress[] a = InetAddress.getAllByName("www.baidu.com");
        for (InetAddress i : a) {
            System.out.println(i);
        }
        InetAddress address = InetAddress.getLocalHost();
        System.out.println(address);
        System.out.println("====================");
        byte[] bs = new byte[] { (byte) 180, 97, 33,107 };
        InetAddress ip = InetAddress.getByAddress(bs);
        System.out.println(ip);

    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

}

网络编程之URL类:(主机当中存放得具体资源)
1、URL:统一资源定位符(Uniform Resource Locator),它表示Internet上某一资源的地址。
InetAddres:硬件资源地址(主机)

public class UrlReader {

public static void main(String[] args) {
    try {
        URL url = new URL("http://www.taoche.com/all/?WT.mc_id=tc114lam");
        InputStreamReader isr = new InputStreamReader(url.openStream());
        BufferedReader br = new BufferedReader(isr);

        String line = null;

        while ((line = br.readLine()) != null) {
            System.out.println(line);
        }

        isr.close();
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

Socket通信过程理论分析:
1、ServerSocket类
//创建服务端程序
ServerSocket server=new ServerSocket(1995);0-65535
Socket s=server.accept();
通过s获得输入输出流,与客户端进行交互
2、Socket类
Socket socket=new Socket(“127.0.0.1”,1995);
通过socket获得输入输出流,与服务器进行交互

3、通信过程

public class Server {

public static List<Socket> sockets = new ArrayList<Socket>();
public static List<String> names = new ArrayList<String>();

public static void main(String[] args) {

    try {
        names.add("笨笨熊");
        names.add("喜洋洋");
        names.add("小灰灰");
        names.add("红太狼");
        names.add("光头强");
        System.out.println("服务器启动!");
        ServerSocket server = new ServerSocket(1995);
        int count = 0;
        while (true) {
            System.out.println("等待客户端连接!");
            Socket s = server.accept();// 等待客户端的连接
            sockets.add(s);
            System.out.println("客户端已经连接,目前在线人数:" + sockets.size() + "!");
            new SocketThread(s, names.get(count++)).start();
            // 服务器为每一个客户端连接分配线程

        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

class SocketThread extends Thread {
private Socket s;
private String name;

public SocketThread(Socket socket, String name) {
    this.s = socket;
    this.name = name;
}

public void run() {
    try {

        BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
        String content = null;
        while (true) {
            content = br.readLine();// 阻塞状态,等待客户端发来消息
            for (Socket socket : Server.sockets) {
                OutputStreamWriter osw = new OutputStreamWriter(socket.getOutputStream());
                osw.write(name + ":" + content + "\n");

                osw.flush();
            }
            System.out.println("日志记录:"+name + ":" + content);

        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

public class Client {

public static void main(String[] args) {
    try {
        Socket s = new Socket("127.0.0.1", 1995);
        new SendTread(s).start();
        new GetThread(s).start();
    } catch (UnknownHostException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

// 发送消息的线程
class SendTread extends Thread {
private Socket s;

public SendTread(Socket s) {
    this.s = s;
}

public void run() {
    try {
        OutputStreamWriter osw = new OutputStreamWriter(s.getOutputStream());
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        while (true) {
            String content = br.readLine();//阻塞状态,是让客户端从键盘输入消息
            osw.write(content + "\n");
            osw.flush();
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}
// 接收消息的线程

class GetThread extends Thread {
private Socket s;

public GetThread(Socket s) {
    this.s = s;

}

public void run() {
    try {

        while (true) {
            System.out.println("客户端启动!");
            BufferedReader br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            String content = br.readLine();//阻塞状态,接服务端发来的消息
            System.out.println(content);
        }

    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值