文章目录
- 网络编程入门知识
- JDK8新特性
- Lambda表达式
- 以多线程为例:
- Lambda结合for循环:
- Stream流
- 获取一个流的2种常用的方式:
- 常用方法
- 终结方法
- 延迟方法
- 案例
网络编程入门知识
软件结构、协议分类、网络通信协议、网络编程三要素、TCP通信协议、文件上传、BIO 、 NIO 与 AIO
JDK8新特性
Lambda表达式
面向对象的思想: 做一件事情,找一个能解决这个事情的对象,调用对象的方法,完成事情.
函数式编程思想:只要能获取到结果,谁去做的,怎么做的都不重要,重视的是结果,不重视过程,比如你去北京,你可以走着也可以坐车,怎么去不重要,重要的是你能到。
使用前提:
必须有接口,且接口中有且仅有一个抽象方法
必须有上下文环境,否则不知道你表达式干啥用的
主要目的是省去了 新建一个实现类来实现接口,把实现接口的重写方法,放在主方法里面来重写了,用Lambda表达式的写法比匿名内部类的写法,简化了很多。
Lambda由3个部分组成:
(参数类型1 参数名1,参数类型2 参数名2) ‐> { 代码}
(parameters) ->{ statements; }
以多线程为例:
// 1匿名内部类
Runnable task = new Runnable() {
@Override
public void run() { // 覆盖重写抽象方法
System.out.println("多线程任务执行!");
}
};
new Thread(task).start(); // 启动线程
//2.Lambda
new Thread( () -> System.out.println("多线程任务执行!") ).start()
Lambda结合for循环:
IntStream.range(0,4).forEach(i->System.out.println("循环变量i:"+i));
例如: 请使用Lambda的格式调用 invokeCook 方法,打印输出 "吃饭啦 ! " 字样:
public interface Cook {
void makeFood();
}
public class Demo {
public static void main(String[] args) {
// TODO 请在此使用Lambda【标准格式】调用invokeCook方法
}
private static void invokeCook(Cook cook) {
cook.makeFood();
}
}
ans
invokeCook(() -> System.out.println("吃饭啦!"));
例子2: 请在此使用Lambda调用invokeCalc方法来计算120+130的结果
public interface Calculator {
int calc(int a, int b);
}
public class Demo {
public static void main(String[] args) {
// 使用Lambda调用invokeCalc方法来计算120+130的结果
}
private static void invokeCalc(int a, int b, Calculator calculator) {
int result = calculator.calc(a, b);
System.out.println("结果是:" + result);
}
}
invokeCalc(120,130,(int a, int b) -> {return a+b;});
省略写法:
1.小括号内参数的类型可以省略;
2. 如果小括号内有且仅有一个参,则小括号可以省略;
3. 如果大括号内有且仅有一个语句,则无论是否有返回值,都可以省略大括号、return关键字及语句分号。
invokeCalc(120,130,(a, b)->a+b); //省略写法:1、3
Stream流
for循环,循环语法关注的是怎么做的问题,循环体里关注的是做什么
代码如下(示例):
//增强for:数组或者list、set
for(String i:list) {
System.out.println(i);
}
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
List<String> listA = new ArrayList<>();
//放入以张开头的元素
for (String s : list) {
if (s.startsWith("张")) {
listA.add(s);
}
}
System.out.println(listA);
//放入长度为三的元素
List<String> listB = new ArrayList<>();
for (String s : listA) {
if (s.length() == 3) {
listB.add(s);
}
}
System.out.println(listB);
}
Stream能给我们带来怎样更加优雅的写法呢?
list.stream()
.filter(s -> s.startsWith("张"))
.filter(s -> s.length() == 3)
.forEach(s -> System.out.println(s));
备注:“Stream流”其实是一个集合元素的函数模型,它并不是集合,也不是数据结构,其本身并不存储任何 元素(或其地址值)
获取一个流的2种常用的方式:
获取一个流非常简单,有以下2种常用的方式:
所有的 Collection 集合都可以通过 stream 默认方法获取流;
Stream 接口的静态方法 of 可以获取数组对应的流。
//1.所有的 Collection 集合
list.stream()
.filter(s -> s.startsWith("张"))
.forEach(s -> System.out.println(s));
Map<String, String> map = new HashMap<>();//map
Stream<String> valueStream = map.values().stream();
Stream<String> keyStream = map.keySet().stream();
Set<String> set = new HashSet<>();
Stream<String> setStream = set.stream();
//2.数组的流
String[] array = {"张三","李四","赵五"};
Stream<String> arrayStream = Stream.of(array);
常用方法
延迟方法:返回值类型仍然是 Stream 接口自身类型的方法,因此支持链式调用。
终结方法:返回值类型不再是 Stream 接口自身类型的方法,因此不再支持类似 StringBuilder 那样的链式调 用。终结方法包括 count 和 forEach 方法 。
终结方法
统计个数:long count();
public static void main(String[] args) {
String[] array = {"张无忌","周芷若","赵敏"};
Stream<String> arrayStream = Stream.of(array);
long count = arrayStream.count();
System.out.println(count);
}
逐一处理:forEach,forEach ,将list的每一个元素s交给函数处理,做了一下输出。
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("张无忌");
list.add("周芷若");
list.add("赵敏");
list.add("张强");
list.add("张三丰");
list.stream().forEach(s -> System.out.println(s));
}
延迟方法
过滤:filter,将一个流转换成子集流
public static void main(String[] args) {
String[] array = {"张无忌","周芷若","赵敏","张丽热巴", "张战","Jay","王菲","张云雷","张云伟"};
Stream<String> arrayStream = Stream.of(array);//流
Stream<String> arrayStream1 =arrayStream.filter(s -> s.startsWith("张"));//将一个流转换成子集流
arrayStream1.forEach(s -> System.out.println(s));//逐一处理终结方法
//arrayStream.forEach(s -> System.out.println(s)); //arrayStream1
//stream has already been operated upon or closed
}
映射:map
public static void main(String[] args) {
String[] array = {"12","22","23","34", "66","88"};
Stream<String> arrayStream = Stream.of(array);//流
//map映射:将字符串类型的整数转换成Integer类型的整数
//Stream<Integer> arrayStream1 = arrayStream.map(name -> {return Integer.parseInt(name);});
Stream<Integer> arrayStream1 = arrayStream.map(name ->Integer.parseInt(name));
arrayStream1.forEach(s -> System.out.println(s));//逐一处理终结方法
}
取用前几个:limit
public static void main(String[] args) {
String[] array = {"12","22","23","34", "66","88"};
Stream<String> arrayStream = Stream.of(array);//流
Stream<String> arrayStream1 = arrayStream.limit(20);
//取用前几个
arrayStream1.forEach(s -> System.out.println(s));//逐一处理终结方法
}
跳过前几个:skip
public static void main(String[] args) {
String[] array = {"12","22","23","34", "66","88"};
Stream<String> arrayStream = Stream.of(array);//流
Stream<String> arrayStream1 = arrayStream.skip(2);//跳过前几个
//如果长度大于元素长度则返回一个长度为0的空流
arrayStream1.forEach(s -> System.out.println(s));//逐一处理终结方法
}
组合:concat,将2个流合并成一个流
public static void main(String[] args) {
Stream<String> arrayStream1 = Stream.of("张无忌");//流1
Stream<String> arrayStream2 = Stream.of("张翠山");//流1
Stream<String> arrayStream3 = Stream.concat(arrayStream1, arrayStream2);
arrayStream3.forEach(s -> System.out.println(s));
}
案例
1、第一个队伍只要名字为3个字的成员姓名;存储到一个新集合中。
2、第一个队伍筛选之后只要前3个人;存储到一个新集合中。
3、第二个队伍只要姓张的成员姓名;存储到一个新集合中。
4、第二个队伍筛选之后不要前2个人;存储到一个新集合中。
5、将两个队伍合并为一个队伍;存储到一个新集合中。
6、根据姓名创建 Person 对象;存储到一个新集合中。(暂未更新)
7、打印整个队伍的Person对象信息。(暂未更新)
public class TestCalc {
public static void main(String[] args) {
// 第一支队伍
ArrayList<String> one = new ArrayList<>();
Collections.addAll(one, "迪丽热巴", "肖战", "Jay", "王菲", "张云雷", "何云伟");
List<String> oneA = new ArrayList<>();
for (String name : one) {
if (name.length() == 3) {
oneA.add(name);
}
}
System.out.println("1、第一个队伍只要名字为3个字的成员姓名:");
for (String name : oneA) {
System.out.println(name);
}
List<String> oneB = new ArrayList<>();
for (int i = 0; i < 3; i++) {
oneB.add(one.get(i));
}
System.out.println("2、 第一个队伍筛选之后只要前3个人:");
for (String list : oneB) {
System.out.println(list);
}
// 第二支队伍
ArrayList<String> two = new ArrayList<>();
Collections.addAll(two, "张无忌", "张三丰", "赵四", "张二狗");
List<String> twoA = new ArrayList<>();
for (String name : two) {
if (name.startsWith("张")) {
twoA.add(name);
}
}
System.out.println("3、 第二个队伍只要姓张的成员姓名:");
for (String name : twoA) {
System.out.println(name);
}
List<String> twoB = new ArrayList<>();
for (int i = 2; i < two.size(); i++) { // i=x 队伍筛选之后不要前x个人
twoB.add(two.get(i));
// twoB.add(two.get(i));
}
System.out.println("4、 第二个队伍筛选之后不要前2个人:");
for (String name : twoB) {
// System.out.println(twoB);
}
System.out.println(twoB);
// 5、 将两个队伍合并为一个队伍;存储到一个新集合中
List<String> totalNames = new ArrayList<>();
totalNames.addAll(one);// Jay 张云雷 何云伟
// totalNames.addAll(oneB);//迪丽热巴 肖战 Jay
totalNames.addAll(two); // 张无忌 张三丰 张二狗
// totalNames.addAll(twoB); //赵四, 张二狗
// 根据姓名创建Person对象;
List<Person> totalPersonList = new ArrayList<>();
for (String name : totalNames) {
totalPersonList.add(new Person(name));
}
System.out.println("5、将两个队伍合并为一个队伍;存储到一个新集合中:");
// 打印整个队伍的Person对象信息。
for (Person person : totalPersonList) {
// System.out.println(person);
}
System.out.println(totalNames);
}// "迪丽热巴", "肖战", "Jay", "王菲", "张云雷", "何云伟"
// "张无忌", "张三丰", "赵四", "张二狗"
}
Person
public class Person {
private String name;
public Person() {}
public Person(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{name='" + name + "'}";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
运行截图: