首页 > 编程语言 >Java基础

Java基础

时间:2023-05-27 14:25:31浏览次数:49  
标签:Java list 基础 System println new public out

Java基础

  1. 将一个对象作为参数传递是值传递还是引用传递?
  • java中只有值传递没有引用传递!!!
  • 无论是基本数据类型还是引用类型都是值传递,引用类型传递的时地址的值
  1. new string()和string的区别?
  • new String是在堆空间中创建对象,而string是直接在常量池中赋值
  • String不能被继承(String是被final修饰的,而被final修饰的类是不能被继承的)
  1. String s = new String("abc");创建了几个对象?
  • 两个,"abc"会被放在常量池,而new出来的对象会被放在堆内存
  1. hashCode()与equals()之间的联系?
  • 如果两个对象相等,那么它们的哈希码一定相同;但是如果两个对象有着相同的哈希码,它们不一定相等
  1. 一定要同时重写 equals() 和 hashCode() 吗?
  • 不一定,如果对象作为键在哈希表中,那么两个方法都要重写,因为 put 和 get 的时候需要用到哈希码和 equals() 方法;如果对象不在哈希表中,仅用来判断是否相等,那么重写 equals() 就行了
  1. static使用注意规范:
    • 静态方法只能访问静态成员,不能直接访问实例成员
    • 实例方法可以访问静态成员,也可以访问实例成员
          public static void main(String[] args) {
              test();
          }
          
          public static void test() {
              System.out.println("test");
          }

          public void test2() {
              test();
          }
          
          public void test3() {
              test2();
          }
  • 静态方法中不可以出现this关键字
  1. 代码块的使用
    • 实例(构造)代码块:无static修饰,属于对象,每次构建对象都会触发一次
    • 使用场景:初始化实例资源
        {
            System.out.println("====实例化代码块被触发====");
        }
  • 静态代码块:属于类,类加载时执行一次
  • 使用场景:在类加载的时候做一些静态数据初始化的操作,以便后续使用
        static {
		    System.out.println("==静态代码块被触发==");
	    }
  1. 单例模式
  • 懒汉式
    需要时才实例化对象,构造器以及实例需私有化,通过静态方法获取实例
        class SingleInstance2 {
    
            private static SingleInstance2 instance;
            
            public static SingleInstance2 getInstance() {
                if (instance == null) {
                    instance = new SingleInstance2();
                }
                return instance;
            }
            
            private SingleInstance2() {
                
            }
        }
    
  • 饿汉式
    直接实例化对象,构造器需私有化,通过类名调用
    class SingleInstance {
        public static SingleInstance instance = new SingleInstance();
    
        private SingleInstance() {
            
        }
    }
    
  1. 静态方法不能够被重写
  2. 被final关键字标记的类不能继承,方法不能重写,变量只能赋值一次
  3. this和super调用构造器只能放在第一行,因此两者不能共存!!!
  4. 抽象类的特征
    • 类有的抽象类都有
    • 抽象类中可以没有抽象方法,但是有抽象方法的必须是抽象类,且继承抽象类时需实现抽象类中所有抽象方法,除非继承类也是抽象类
    • 抽象类不能new,只能继承
  5. final与abstract互斥,加了final就不能加abstract
  6. JDK1.8开始后新增了哪些方法?
    • 默认方法:default修饰,实现类对象调用
    • 静态方法:static修饰,必须用当前接口名调用
    • 私有方法:private修饰,jdk9开始才有的,只能在接口内部调用

以下为示例代码:

    interface JDK8之后新增的方法 {

        /**
         * jdk1.8开始: 默认方法(实例方法)
         * 必须用default修饰,默认用public修饰
         * 只能由实现类对象调用
         */
        default void run() {
            go();
            System.out.println("跑的挺快···");
        }
        
        
        /**
         * 静态方法,必须使用static修饰,默认使用public修饰
         * 必须接口名自己调用
         */
        static void inAddr() {
            System.out.println("我们都在学习Java···");
        }
        
        
        /**
         * 私有方法,jdk1.9才开始支持,必须在接口内部才能被访问
         */
        private void go() {
            System.out.println("开始跑```");
        }
    }

    class sportMan implements JDK8之后新增的方法 {
        
    }

    class test {
        public static void main(String[] args) {
            sportMan s = new sportMan();
            s.run();
            JDK8之后新增的方法.inAddr();
        }
    }

  1. 接口的注意规范
    1. 接口不能创建对象
    1. 一个类实现多个接口,多个接口中有同样的静态方法不冲突(因为静态方法只能自己类自己调)
    1. 一个类继承了父类,同时又实现了接口,父类中与接口中有同名方法,默认使用父类的
    1. 一个类实现多个接口,多个接口中存在同名的默认方法,不冲突,这个类重写该方法即可。
    1. 一个接口继承多个接口,是没有问题的,如果多个接口中存在规范冲突则不能多继承
  1. 多态中成员访问特点

    • 方法调用:编译看左边,运行看右边
    • 变量调用:编译看左边,运行看左边 (多态侧重行为多态)
  2. 多态的优点
    (1)在多态形式下,右边对象可以实现解耦合,便于扩展和维护
    (2)定义方法的时候,使用父类型作为参数,该方法就可以接收这父类的一切子类对象,体现出多态的拓展性与便利

  3. 匿名内部类可以作为方法的实际参数传递

  4. Objects类中的equals方法更安全,可以避免空指针问题

  5. JDK8新增的日期类

    • LocalDate:不包含具体时间的日期
    • LocalTime:不含日期的时间
    • LocalDateTime:包含了日期和时间
    • Instant:代表时间戳
    • DateTimeFormatter:用作时间格式化和解析的
    • Duration:用于计算两个 “时间” 间隔
    • Period:用于计算两个 “日期” 间隔
  6. 正则表达式的使用


    详细解析看这里->https://github.com/ziishaned/learn-regex/blob/master/translations/README-cn.md

  7. Arrays的使用

        public static void arrayTest() {
    	int[] a = { 12, 2, 1, 5, 43, 32, 22};
    	System.out.println(Arrays.toString(a));
    	Arrays.sort(a);
    	System.out.println(Arrays.toString(a));
    	System.out.println(Arrays.binarySearch(a, 2));
    	Integer[] a2 = {21, 32, 2, 4, 222, 41};
    	/**
    	 * 参数一:被排序的数组必须是引用类型的元素
    	 * 参数二:匿名内部类对象,代表一个比较器对象
    	 */
    	Arrays.sort(a2, new Comparator<Integer>() {
    
    		@Override
    		public int compare(Integer o1, Integer o2) {
    			return o2 - o1;
    		}
    	});
    	System.out.println(Arrays.toString(a2));
    }
    
    public static void arrayTest2() {
    	student2[] s = new student2[2];
    	s[0] = new student2("韩信", 18, 66);
    	s[1] = new student2("李白", 20, 88);
    	Arrays.sort(s, new Comparator<student2>() {
    
    		@Override
    		public int compare(student2 o1, student2 o2) {
    			// 浮点型可以这样
                // return Double.compare(o2.score, o1.score);
    			return o2.score - o1.score;
    		}
    	});
    	System.out.println(Arrays.toString(s));
    }
    
  8. Lambda表达式的使用

    • 作用:简化匿名内部类的代码写法
    • 注意事项:Lambda表达式只能简化函数式接口的匿名内部类写法
    • 函数式接口表示里面只能有一个抽象方法
      代码如下:
        public class Lambda表达式的用法 {
            
            public static void main(String[] args) {
                // 标准匿名内部类
                sports s = new sports() {
                    
                    @Override
                    public void swim() {
                        System.out.println("游泳中~~~");
                    }
                };
                go(s);
                
                // Lambda表达式实现内部类写法
                sports s2 = () -> { System.out.println("游泳中~~~");};
                go(s2);
                
                // 继续简化
                go(() -> { System.out.println("游泳中~~~");});
            }
            
            public static void go(sports s) {
                System.out.println("开始~~~");
                s.swim();
                System.out.println("结束~~~");
            }
    
        }
    
        @FunctionalInterface // 加上这个注解表示这个接口只能是函数式接口,里面只能有一个抽象方法
        interface sports {
            void swim();
        }
    
    • Lambda表达式的省略写法
    1. 参数类型可以省略不写
            Arrays.sort(ages1,(Integer o1,Integer o2) ->{
                return o2 - o1;//降序
            });
    
            Arrays.sort(ages1,(o1, o2) ->{
                return o2 - o1;//降序
            });
    
    1. 如果只有一个参数,参数类型可以省略,同时()也可以省略
            btn.addActionListener( (ActionEvent e)-> {
            system.out.println("有人点我,点我,点我!!");
            });
    
            btn.addActionListener( e -> {
            system.out.println("有人点我,点我,点我!!");
            });
    
    1. 如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写,同时要省略分号!
            btn. addActionListener( e -> system.out.println("有人点我,点我,点我!!"));
    
    1. 如果Lambda表达式的方法体代码只有一行代码。可以省略大括号不写。此时,如果这行代码是return语句,必须省略return不写,同时也必须省略";"不写
            Arrays.sort(ages1,(Integer o1,Integer o2) ->{
                return o2 - o1;//降序
            });
    
            Arrays.sort(ages1,(o1, o2) -> o2 - o1);
    
  9. 集合

    Collection集合


    List集合的遍历

    1. 迭代器遍历
    public static void testIterator() {
            Collection list = new ArrayList<>();
            list.add(12);
            list.add(13);
            list.add(14);
            list.add(15);
            Iterator<Integer> it = list.iterator();
            while (it.hasNext()) {
                int value = (int) it.next();
                System.out.println(value);
            }
        }
    

    注意:在迭代器中删除元素时不要使用集合的remove,需要使用迭代器的remove
    2. foreach/增强for循环

    public static void testForeach() {
    	Collection<Integer> list = new ArrayList<>();
    	list.add(12);
    	list.add(13);
    	list.add(14);
    	list.add(15);
    	for(Integer i: list) {
    		System.out.println(i);
    	}
    }
    

    注意:
    (1) 增强for循环与for循环的区别就是增强for循环安全,循环内无法改变变量值,for循环可以
    (2) 增强for循环无法遍历删除元素值
    3. Lambda表达式

    public static void testForEach() {
    	Collection<Integer> list = new ArrayList<>();
    	list.add(12);
    	list.add(13);
    	list.add(14);
    	list.add(15);
    	list.forEach(new Consumer<Integer>() {
    
    		@Override
    		public void accept(Integer t) {
    			System.out.println(t);
    		}
    	});
    	
    	// Lambda表达式简化
    	list.forEach(s -> System.out.println(s));
    	
    	// 再次简化
    	list.forEach(System.out::println);
    }
    

    注意:Lambda表达式也无法遍历删除元素值
    4. for循环

    public static void testFor() {
    	List<String> list = new ArrayList<>();
    	list.add("12");
    	list.add("12");
    	list.add("13");
    	list.add("14");
    	list.add("15");
    	for (int i = 0; i < list.size(); i++) {
    		if (list.get(i).equals("12")) {
    			list.remove("12");
    		}
    	}
    	System.out.println(list);
    }
    

    注意:运行不报错,但会漏删
    解决方法:倒着删,或者每次删完指针前移一位

    public static void testFor() {
    	List<String> list = new ArrayList<>();
    	list.add("12");
    	list.add("12");
    	list.add("13");
    	list.add("14");
    	list.add("15");
    	for (int i = list.size()-1; i >= 0; i--) {
    		if (list.get(i).equals("12")) {
    			list.remove("12");
    		}
    	}
    	System.out.println(list);
    }
    

    Set集合

    (1)HashSet集合
    特点:无序,不重复,无索引
    底层架构:数组+链表+红黑树(当链表长度到8时,自动转为红黑树)也叫哈希表

    (2)LinkedHashSet集合
    特点:有序,不重复,无索引
    底层架构:哈希表,只是每个元素多了一个双链表记录存储的顺序

    (3)TreeSet集合
    特点:不重复,无索引,可排序(按照元素大小默认升序排列)
    底层架构:红黑树
    注意:TreeSet集合是一定要排序的,可以将元素按照指定的规则进行排序。

    • 自定义数据类型使用TreeSet
    1. 自定义数据类型实现Comparable接口
    public class Person implements Comparable<Person>{
    
        @Override
        public int compareTo(Person o) {
            return score - o.score >= 0 ? 1 : -1;
        }
    }
    
    public static void testTreeSet() {
    	Set<Person> sets = new TreeSet<Person>();
    	sets.add(new Person("韩信", 20, 66));
    	sets.add(new Person("韩信", 20, 66));
    	sets.add(new Person("李白", 18, 88));
    	System.out.println(sets);
    }
    
    1. 集合自带比较器
    public static void testTreeSet() {
    	Set<Person> sets = new TreeSet<Person>(new Comparator<Person>() {
    
    		@Override
    		public int compare(Person o1, Person o2) {
    			// 浮点型使用Double.compare方法
    			// return Double.compare(o1.getScore(), o2.getScore());
    			return o1.getScore() - o2.getScore() >= 0 ? 1 : -1;
    		}
    	});
    	sets.add(new Person("韩信", 20, 66));
    	sets.add(new Person("韩信", 20, 66));
    	sets.add(new Person("李白", 18, 88));
    	System.out.println(sets);
    }
    
    
    Lambda表达式简化后:
    
    public static void testTreeSet() {
    	Set<Person> sets = new TreeSet<Person>((o1, o2) -> o1.getScore() - o2.getScore() >= 0 ? 1 : -1);
    	sets.add(new Person("韩信", 20, 66));
    	sets.add(new Person("韩信", 20, 66));
    	sets.add(new Person("李白", 18, 88));
    	System.out.println(sets);
    }
    

    Map集合


    Map集合遍历

    1. 键找值
        public static void testKeySet() {
            Map<String, Integer> maps = new HashMap<String, Integer>();
            maps.put("水果", 12);
            maps.put("鸡腿", 20);
            maps.put("鱼", 30);
            System.out.println(maps);
            
            Set<String> keys = maps.keySet();
            for (String key: keys) {
                System.out.println(key + ":" + maps.get(key));
            }
        }
    
    1. 键值对
        public static void testEntrySet() {
            Map<String, Integer> maps = new HashMap<String, Integer>();
            maps.put("水果", 12);
            maps.put("鸡腿", 20);
            maps.put("鱼", 30);
            System.out.println(maps);
            
            Set<Entry<String, Integer>> sets = maps.entrySet();
            for (Entry<String, Integer> key: sets) {
                System.out.println(key.getKey() + ":" + key.getValue());
            }
        }
    
    1. Lambda表达式
        public static void testForEach() {
            Map<String, Integer> maps = new HashMap<String, Integer>();
            maps.put("水果", 12);
            maps.put("鸡腿", 20);
            maps.put("鱼", 30);
            System.out.println(maps);
            
            maps.forEach(new BiConsumer<String, Integer>() {
    
                @Override
                public void accept(String t, Integer u) {
                    System.out.println(t + ":" + u);
                }
            });
            
            // 简化后
            maps.forEach((t, u) -> System.out.println(t + ":" + u));
        }
    
  10. Stream流
    目的:简化集合和数组操作的API

    public static void testStream() {
    	List<String> list = new ArrayList<String>();
    	Collections.addAll(list, "韩信", "李白", "孙悟空", "孙权");
    	list.stream().filter(t -> t.startsWith("孙") && t.length() == 3).forEach(System.out::println);; 
    }
    


    public static void main(String[] args) {
    	// Collection集合获取流
    	Collection<String> list = new ArrayList<>();
    	Stream<String> stream = list.stream();
    
    	// Map集合获取流
    	Map<String, Integer> map = new HashMap<>();
    	// 键流
    	Stream<String> keyStream = map.keySet().stream();
    	// 值流
    	Stream<Integer> vauleStream = map.values().stream();
    	// 键值对流
    	Stream<Entry<String, Integer>> entryStream = map.entrySet().stream();
    	
    	// 数组获取流
    	String[] s = {"韩信","李白","孙悟空","孙策"};
    	Stream<String> stream2 = Arrays.stream(s);
    	Stream<String> stream3 = Stream.of(s);
    }
    

    public static void testStreamMethod() {
    	List<String> list = new ArrayList<String>();
    	Collections.addAll(list, "韩信", "李白", "孙悟空", "孙权");
    	// 跳过前面两个元素
    	list.stream().skip(2).forEach(System.out::println);
    	// 获取前面两个元素
    	list.stream().limit(2).forEach(System.out::println);
    	// map加工方法
    	list.stream().map(s -> "王者:" + s).forEach(System.out::println);
    	// 封装成student对象
    	list.stream().map(s -> new student(s)).forEach(s -> System.out.println(s));
    	list.stream().map(student::new).forEach(System.out::println);
    	// 合并流
    	Stream<String> s1 = Stream.of("韩信", "李白");
    	Stream<String> s2 = list.stream().skip(2);
    	Stream<String> s3 = Stream.concat(s1, s2);
    	s3.forEach(System.out::println);
    }
    

    Stream流的收集操作

    public static void testCollect() {
    	List<String> list = new ArrayList<String>();
    	Collections.addAll(list, "韩信", "李白", "孙悟空", "孙权");
    	
    	// 收集流
    	// list
    	Stream<String> s = list.stream().skip(2);
    	List<String> list2 = s.collect(Collectors.toList());
    	System.out.println(list2);
    	
    	// set
    	// 注意:流只能使用一次,如需再次使用需重新创建流
    	Stream<String> s2 = list.stream().skip(2);
    	Set<String> set = s2.collect(Collectors.toSet());
    	System.out.println(set);
    	
    }
    
  11. 红黑树

    红黑树调整

    (1)父节点为红色,叔叔节点也是红色
    调整前

    调整后

    (2)父节点为红,叔叔节点是黑色
    调整前

    调整后

  12. 泛型的使用
    (1)通配符“?”的使用

    public static void testGeneric() {
            ArrayList<DaBen> list1 = new ArrayList<DaBen>();
            list1.add(new DaBen());
            list1.add(new DaBen());
            list1.add(new DaBen());
            ArrayList<AoDi> list2 = new ArrayList<AoDi>();
            list2.add(new AoDi());
            list2.add(new AoDi());
            list2.add(new AoDi());
            go(list1);
            go(list2);
            
        }
        
        public static void go(ArrayList<?> list) {
            
        }
    
        class car {
            
        }
    
        class DaBen extends car {
            
        }
    
        class AoDi extends car {
            
        }
    

    (2)泛型的上下限

    • ? extends Car:?必须是Car或者是其子类 泛型上限
    • ? super Car:?必须是Car或者是其父类 泛型下限
    public static void go(ArrayList<? extends car> list) {
    	
    }
    public static void go(ArrayList<? super car> list) {
    	
    }
    
  13. 异常

  14. 日志


  15. IO流







    (1)字节流,字符流如何使用?

    • 字节流适合做一切文件数据的拷贝(音视频,文本)
    • 字节流不适合读取中文内容输出
    • 字符流适合做文本文件的操作(读,写)

    (2)对象序列化

    注意:序列化对象需实现Serializable接口

    (3)对象反序列化

    (4)打印流



    (5)Properties

    (6)IO框架

  16. 多线程
    (1)线程的创建方式

    • 继承Thread类
    • 实现Runnable接口

    • JDK5.0新增:实现Callable接口
      由于前两种创建的线程均不能直接返回结果,故在JDK5.0提供了Callable和FutureTask来实现
        public class Callable接口的使用 {
            
            public static void main(String[] args) {
                // 该类为Callable接口类
                MyCallable myCallable = new MyCallable(100);
                // 该类为Runnable接口类
                FutureTask<String> futureTask = new FutureTask<String>(myCallable);
                Thread thread = new Thread(futureTask);
                thread.start();
                
                MyCallable myCallable2 = new MyCallable(200);
                FutureTask<String> futureTask2 = new FutureTask<String>(myCallable2);
                Thread thread2 = new Thread(futureTask2);
                thread2.start();
                
                try {
                    // get方法获取返回值,如果任务没有执行完成则会等待,任务完成才会提取结果
                    String result = futureTask.get();
                    String result2 = futureTask2.get();
                    System.out.println("第一个结果:" + result);
                    System.out.println("第二个结果:" + result2);
                } catch (Exception e) {
                    e.printStackTrace();
                }
                
            }
    
        }
    
        class MyCallable implements Callable<String> {
            
            private int n;
            
            public MyCallable(int n) {
                super();
                this.n = n;
            }
    
    
    
            @Override
            public String call() throws Exception {
                int sum = 0;
                for (int i = 0; i <= n; i++) {
                    sum += i;
                }
                return "子线程运行的结果是:" + sum;
            }
            
        }
    
    




    (2)线程安全出现的原因

    • 存在多线程并发
    • 同时访问共享资源
    • 存在修改共享资源
      解决方法
      • 同步代码块


        synchronized()括号里使用共享资源作为锁对象较好

      • 同步方法

      • Lock锁

    (3)线程通信
    主要是生产者与消费者这一思想

    线程池(面试重点)










    定时器


    public static void main(String[] args) {
    	Timer timer = new Timer();
    	timer.schedule(new TimerTask() {
    		
    		@Override
    		public void run() {
    			System.out.println(Thread.currentThread().getName() + "执行一次!");
    		}
    	}, 3000, 2000);
    }
    

    public static void main(String[] args) {
    	ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
    	pool.scheduleAtFixedRate(new TimerTask() {
    		
    		@Override
    		public void run() {
    			System.out.println(Thread.currentThread().getName() + "执行AAA!");
    		}
    	}, 0, 2, TimeUnit.SECONDS);
    	
    	pool.scheduleAtFixedRate(new TimerTask() {
    		
    		@Override
    		public void run() {
    			System.out.println(Thread.currentThread().getName() + "执行BBB!");
    		}
    	}, 0, 2, TimeUnit.SECONDS);
    }
    

    线程的生命周期

  17. 网络编程

    网络通信


    (1)IP地址

    (2)端口号


    (3)协议


    UDP通信


    实现一发一收
    
    
    client(客户端)
    
    public static void main(String[] args) throws Exception{
    	// 创建发送端对象,发送端自带默认端口号
    	DatagramSocket socket = new DatagramSocket();
    	
    	// 创建发送内容
    	byte[] data = "hello, 我是你爹!".getBytes();
    	DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getLocalHost(), 6666);
    	
    	// 发送数据
    	socket.send(packet);
    
        // 关闭端口
    	socket.close();
    }
    
    server(服务端)
    
    public static void main(String[] args) throws Exception{
    	// 创建接收端对象
    	DatagramSocket socket = new DatagramSocket(6666);
    	
    	// 创建接收容器
    	byte[] data = new byte[1024 * 64];
    	DatagramPacket packet = new DatagramPacket(data, data.length);
    	
    	// 等待接收数据
    	socket.receive(packet);
    
        // 获取客户端信息
    	String ip = packet.getAddress().toString();
    	int port = packet.getPort();
    	System.out.println("获取来自ip:" + ip.substring(1, ip.length()) + ",端口:" + port + "的信息!");
    	
    	// 取出数据
    	// 读多少,取多少
    	int length = packet.getLength();
    	String s = new String(data, 0, length);
    
        // 关闭端口
    	socket.close();
    }
    
    
    实现多发多收
    
    client(客户端)
    
    public static void main(String[] args) throws Exception{
    	// 创建发送端对象,发送端自带默认端口号
    	DatagramSocket socket = new DatagramSocket();
    	
    	// 获取键盘输入内容
    	Scanner scan = new Scanner(System.in);
    	String content = scan.next();
    	while (true) {
    		// 创建发送内容
    		byte[] data = content.getBytes();
    		DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getLocalHost(), 6666);
    		// 发送数据
    		socket.send(packet);
    		
    		if (content.equals("exit")) {
    			break;
    		}
    		content = scan.next();
    	}
    	
    	socket.close();
    	scan.close();
    }
    
    server(服务端)
    
    
    public static void main(String[] args) throws Exception{
    	// 创建接收端对象
    	DatagramSocket socket = new DatagramSocket(6666);
    	
    	// 创建接收容器
    	byte[] data = new byte[1024 * 64];
    	DatagramPacket packet = new DatagramPacket(data, data.length);
    	
    	while(true) {
    		// 等待接收数据
    		socket.receive(packet);
    		
    		String content = packet.getData().toString();
    		
    		if(content.equals("exit")) {
    			break;
    		}
    		
    		// 获取客户端信息
    		String ip = packet.getAddress().toString();
    		int port = packet.getPort();
    		System.out.println("获取来自ip:" + ip.substring(1, ip.length()) + ",端口:" + port + "的信息!");
    		
    		// 取出数据
    		// 读多少,取多少
    		int length = packet.getLength();
    		String s = new String(data, 0, length);
    		System.out.println(s);
    		
    	}
    	
    	socket.close();
    }
    



    TCP通信



    public static void main(String[] args) {
    	try {
    		// 创建Socket通信管道,请求有服务端的连接
    		Socket socket = new Socket("127.0.0.1", 6666);
    		// 从Socket管道中获取字节输出流,负责发送数据
    		OutputStream os = socket.getOutputStream();
    		// 把低级的字节流包装成打印流
    		PrintStream ps = new PrintStream(os);
    		// 发送消息
    		ps.println("hello啊!");
    		ps.flush();
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }
    
    
    
    public static void main(String[] args) {
    	try {
    		// 注册端口
    		ServerSocket server = new ServerSocket(6666);
    		// 必须调用accept方法,等待客户端的socket请求,建立socket通信
    		Socket socket = server.accept();
    		// 获取输入流
    		InputStream is = socket.getInputStream();
    		// 封装成缓冲字符流
    		BufferedReader br = new BufferedReader(new InputStreamReader(is));
    		// 读取数据
    		String msg;
    		if((msg = br.readLine()) != null) {
    			System.out.println(socket.getRemoteSocketAddress() + ":" + msg);
    		}
    		
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }
    



    解决方法: 使用多线程,并使用线程池进行优化

    
    client(客户端)
    
    public static void main(String[] args) {
    	try {
    		// 创建Socket通信管道,请求有服务端的连接
    		Socket socket = new Socket("127.0.0.1", 6666);
    		// 从Socket管道中获取字节输出流,负责发送数据
    		OutputStream os = socket.getOutputStream();
    		// 把低级的字节流包装成打印流
    		PrintStream ps = new PrintStream(os);
    		Scanner scan = new Scanner(System.in);
    		while (true) {
    			String msg = scan.nextLine();
    			// 发送消息
    			ps.println(msg);
    			ps.flush();
    		}
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }
    
    server(服务端)
    
    	// 使用线程池进行优化
    private static ExecutorService pools = new ThreadPoolExecutor(3, 5, 5, TimeUnit.SECONDS, new ArrayBlockingQueue<>(2), 
    		Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());
    
    public static void main(String[] args) {
    	try {
    		// 注册端口
    		ServerSocket server = new ServerSocket(6666);
    		while (true) {
    			// 必须调用accept方法,等待客户端的socket请求,建立socket通信
    			Socket socket = server.accept();
    			// 使用线程池进行优化
    			MyThreadReader runnable = new MyThreadReader(socket);
    			pools.execute(runnable);
    			
    		}
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }
    
    

    TCP通信实战案例-即时通信

    client(客户端)
    
    public class Client3 {
    
        public static void main(String[] args) {
            try {
                // 创建Socket通信管道,请求有服务端的连接
                Socket socket = new Socket("127.0.0.1", 6666);
                
                // 创建一个独立的线程用于接收服务端发来的消息
                new Thread(new ClientRunnable(socket)).start();
                
                // 从Socket管道中获取字节输出流,负责发送数据
                OutputStream os = socket.getOutputStream();
                // 把低级的字节流包装成打印流
                PrintStream ps = new PrintStream(os);
                // 发送数据
                Scanner scan = new Scanner(System.in);
                while (true) {
                    String msg = scan.nextLine();
                    // 发送消息
                    ps.println(msg);
                    ps.flush();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    class ClientRunnable implements Runnable {
        
        private Socket socket;
    
        public ClientRunnable(Socket socket) {
            super();
            this.socket = socket;
        }
        
        @Override
        public void run() {
            try {
                // 获取输入流
                InputStream is = socket.getInputStream();
                // 封装成缓冲字符流
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                // 读取数据
                String msg;
                while ((msg = br.readLine()) != null) {
                    System.out.println("收到消息:" + msg);
                } 
            } catch (Exception e) {
                System.out.println(socket.getRemoteSocketAddress() + "下线了!");
            }
        }
    
    }
    
    server(服务端)
    
    public class Server3 {
        public static ArrayList<Socket> allOnlineSockets = new ArrayList<Socket>();
        
        public static void main(String[] args) {
            try {
                // 注册端口
                ServerSocket server = new ServerSocket(6666);
                while (true) {
                    // 必须调用accept方法,等待客户端的socket请求,建立socket通信
                    Socket socket = server.accept();
                    allOnlineSockets.add(socket);
                    new Thread(new MyRunnable(socket)).start();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    
    class MyRunnable implements Runnable {
        private Socket socket;
        
        public MyRunnable(Socket socket) {
            super();
            this.socket = socket;
        }
    
        @Override
        public void run() {
            try {
                // 获取输入流
                InputStream is = socket.getInputStream();
                // 封装成缓冲字符流
                BufferedReader br = new BufferedReader(new InputStreamReader(is));
                // 读取数据
                String msg;
                while ((msg = br.readLine()) != null) {
                    System.out.println(socket.getRemoteSocketAddress() + "发来了:" + msg);
                    // 转发信息
                    sendMsgTOAll(msg);
                } 
            } catch (Exception e) {
                System.out.println(socket.getRemoteSocketAddress() + "下线了!");
            }
        }
    
        private void sendMsgTOAll(String msg) throws Exception{
            for(Socket socket: Server3.allOnlineSockets) {
                PrintStream ps = new PrintStream(socket.getOutputStream());
                ps.println(msg);
                ps.flush();
            }
        }
    }
    
    
  18. Junit单元测试

  19. 反射







    
    获取构造器
    
    public static void main(String[] args) throws Exception {
    	// 获取类对象
    	Class c = Student.class;
    	// 获取Constructor对象
    	// 该方法只能拿public的
    	Constructor[] c1 = c.getConstructors();
    	for (Constructor constructor : c1) {
    		System.out.println(constructor.getName() + "=====>" + constructor.getParameterCount());
    	}
    	// 该方法可以拿所有的构造器
    	Constructor[] c2 = c.getDeclaredConstructors();
    	for (Constructor constructor : c2) {
    		System.out.println(constructor.getName() + "=====>" + constructor.getParameterCount());
    	}
    	// 获取某个构造器,只能拿public
    	Constructor<Student> c3 = c.getConstructor(String.class, int.class);
    	System.out.println(c3);
    	// 获取某个构造器,全部可以拿
    	Constructor<Student> c4 = c.getDeclaredConstructor();
    	System.out.println(c4);
    	// 如果遇到了私有构造器可以暴力反射
    	c4.setAccessible(true);
    	Student s = c4.newInstance();
    	System.out.println(s);
    	
    }
    
    
    获取变量
    
    public static void testFields() throws Exception {
    	Class c = Student.class;
    	Field[] fields = c.getFields();
    	for (Field field : fields) {
    		System.out.println(field.getName() + "=====>" + field.getType());
    	}
    	
    	Constructor<Student> constructor = c.getDeclaredConstructor();
    	constructor.setAccessible(true);
    	Field ageF = c.getDeclaredField("age");
    	Field ageN = c.getDeclaredField("name");
    	ageF.setAccessible(true);
    	ageN.setAccessible(true);
    	Student student = constructor.newInstance();
    	ageF.set(student, 30);
    	ageN.set(student, "韩信");
    	System.out.println(student);
    	int age = (int) ageF.get(student);
    	String name = (String) ageN.get(student);
    	System.out.println(name + ":" + age);
    }
    
    获取方法
    
    public static void testMethods() throws Exception {
    	Class c = Student.class;
    	Method[] methods = c.getDeclaredMethods();
    	for (Method method : methods) {
    		System.out.println(method.getReturnType() + "=====" + method.getName());
    	}
    	
    	Method method = c.getDeclaredMethod("getName");
    	Student student = new Student("韩信", 20);
    	method.setAccessible(true);
    	System.out.println(method.invoke(student));
    }
    
    强行向Integer类型的ArrayList添加String类型数据
    
    public static void testList() throws Exception{
    	List<Integer> list = new ArrayList<>(); 
    	list.add(22);
    	list.add(11);
    	list.add(33);
    	
    	Class c = list.getClass();
    	Method method = c.getDeclaredMethod("add", Object.class);
    	method.invoke(list, "hello");
    	System.out.println(list);
    }
    


  20. 注解



  21. 动态代理




  22. XML知识

    约束文档







    XML解析






    XML文件的信息检索技术:XPath



  23. 装饰设计模式

标签:Java,list,基础,System,println,new,public,out
From: https://www.cnblogs.com/zhou-shuai/p/17436661.html

相关文章

  • Day2-java泛型与集合
     ArrayList类的使用Set接口及实现类的使用了解对象顺序,Comparable接口及其使用Queue接口和实现类的使用了解Map接口及实现类的使用Collections类的实用方法操作List对象StreamAPI的使用了解泛型类型 取出和输入不用强制类型转换泛型是带一个或多个类型......
  • java中HashMap的实现原理
    HashMap是Java中常用的一种存储结构,它通过哈希表实现了快速查找数据的功能,下面是它的具体实现原理:HashMap内部存储结构HashMap的内部实现是一个数组和一个链表组成的。数组称为哈希表,用于保存实际存储的数据,链表则用于处理哈希冲突,即不同的键值对可能会被存储到哈希表的同一个位置......
  • jdepend java 包依赖分析库
    jdepend是一个java库,可以通过便利源码以及javaclass生成每个java包的质量metrics说明对于比较关心代码质量,或者需要在持续交付中关注质量metrics的jdepend是一个值得使用的工具参考资料https://github.com/clarkware/jdepend......
  • liteflow 一个强大的java 规则框架
    liteflow是一个java规则引擎,融合了编排以及规则引擎的能力,功能上很强大,支持比较复杂的编排(swtich,when,if,while,for。。。)同时还支持的不少的脚本引擎,我们同时还可以将规则存储在外部,实现一些规则管理以及reload说明liteflow对于java生态集成的特别好,是一个很不错的开源规则引......
  • 小马哥Java分布式架构训练营第一期服务治理-鱼龙潜跃水成文
    小马哥Java分布式架构训练营第一期服务治理download:3w51xuebccom使用Netty和SpringBoot实现仿微信的示例在本文中,我们将使用Netty和SpringBoot框架来创建一个简单的聊天应用程序,类似于微信。这个应用程序将支持多用户聊天和即时消息发送。下面让我们来一步步看看如何实现。第一......
  • JAVA的内部类
    JAVA的内部类写在一个类里面的类就叫内部类分类成员内部类:写在成员位置的,属于外部类的成员静态内部类:是一种特殊的成员内部类局部内部类:将内部类定义在方法里面匿名内部类:隐藏了名字的内部类,可以写在成员位置也可以写在局部位置获取成员内部类的两种方法当成......
  • Java语言的简单介绍
    1.计算机语言概述​计算机语言是一种特殊的语言。因为它是用于人与计算机之间传递信息的,所以人和计算机都能“读懂”。具体地说,一方面,人们要使用计算机语言指挥计算机完成某种特定动作,就必须对这种工作进行特殊描述,所以它能够被人们读懂。另一方面,计算机必须按计算机语言描......
  • java开发学习框架
    Java基础1.1.Java简介与安装1.2.Java基本语法1.3.数据类型与变量1.4.运算符与表达式1.5.流程控制(分支与循环)1.6.数组面向对象编程2.1.类与对象2.2.继承与多态2.3.接口与抽象类2.4.封装与访问控制2.5.重载与覆盖2.6.Java内存管理与垃圾回收Java常用......
  • 1.1. Java简介与安装
    Java简介Java是一种广泛使用的计算机编程语言,由JamesGosling和他的团队在SunMicrosystems公司开发,于1995年首次发布。Java的设计理念是“一次编写,到处运行”,这意味着Java应用程序可以在任何支持Java运行时环境(JRE)的设备上运行,而无需重新编译。Java的主要特点包括:面向对象:Java......
  • Java基本语法
    类与文件名在Java中,每个程序都是以类为基础进行编写的。一个简单的Java程序通常包含一个类,类名应该以大写字母开头。Java源代码文件的文件名必须与类名相同,并以.java作为文件扩展名。例如,下面是一个名为HelloWorld的简单Java程序:publicclassHelloWorld{publ......