笔记-迎难而上之Java基础进阶-终
程序员文章站
2022-07-02 18:05:43
使用Stream流的方式,遍历集合 两种获取流的方式 java.util.stream.Stream是Java 8 新加入的最常用的流接口 获取一个非常简单,有一下几种常用的方式: 所有的Collection集合都可以通过stream默认方法获取流(Collection单列集合),该类有一个默认方法 ......
使用stream流的方式,遍历集合
import java.util.*; public class streamdemo{ public static void main(string[] args){ list<string> list = new arraylist<>(); list.add("张无忌"); list.add("周芷若"); list.add("赵敏"); list.add("张强"); list.add("张三丰"); //创建stream流 list.stream() //只要姓张的 .filter(name->name.startswith("张")) //只要长度等于三的 .filter(name->name.length()==3) .foreach(name->system.out.println(name)); } }
两种获取流的方式
java.util.stream.stream
获取一个非常简单,有一下几种常用的方式:
所有的collection集合都可以通过stream默认方法获取流(collection单列集合),该类有一个默认方法"stream",他会返回一个流,所有的collection集合的子类都可以通过该方法获取stream流
stream接口的静态方法 of 可以获取数组对应的流
static
public class streamdemo1{ public static void main(string[] args){ //把集合转换为stream流 list<string> list = new arraylist<>(); //调用方法stream,可以把集合转换成流对象 stream<string> stream1=list.stream(); //set集合也是一个单列集合,继承自collection接口,所以可以通过stream获取流对象 set<string> set = new hashset<>(); stream<string> stream2 = set.stream(); //map集合是双列集合,不是collection接口的子类,获取stream需要间接获取 map<string,string> map = new hashmap<>(); //通过keyset()方法先把键key获取出来,存储到set集合中去,就可以获取key的stream流了 set<string> keyset = map.keyset(); stream<string> stream3 = keyset.stream(); //获取值得流,可以通过方法hashmap的方法values();该方法返回的类型是一个collection集合 collection<string> values = map.values(); stream<string> stream4 = values.stream(); //获取键值对 set<map.entry<string,string>> entries = map.entryset(); stream<map.entry<string,string>> stream5 = entries.stream(); //通过stream类中的静态方法 of 把数组转换成流对象 stream<integer> stream6 = stream.of(1,2,3,4,5); integer[] arr = {1,2,3,4,5}; stream<integer> stream7 = stream.of(arr); } }
stream流中的常用方法_foreach
延迟方法:返回值类型仍然是stream接口自身类型的方法
终结方法:返回值类型不再是stream接口自身类型的方法
import java.util.stream.*; public class foreachdemo{ public static void main(string[] args){ //创建一个stream流 stream<string> stream = stream.of("云想衣裳花想容","春风扶槛露华浓","若非群玉山头见","会向瑶台月下逢"); //使用stream流中的方法foeach对stream流中的数据进行遍历 //该方法接收一个consumer接口函数,会将每一个流元素交个该函数进行处理 stream.foreach((string name)->{system.out.println(name);}); } }
filter方法
filter方法的参数是predicate接口,该接口有的方法
import java.util.stream.*; public class filterdemo{ public static void main(string[] args){ stream<string> stream1 = stream.of("张三丰","张翠山","赵敏","周芷若","张无忌"); //filter方法的参数predicate是一个函数式接口,所以可以传递lambda //predicate接口的test方法返回值类型是boolean stream<string> stream2 = stream1.filter((string name)->{ return name.startswith("张");}); //遍历集合 stream2.foreach((string name)->{system.out.println(name);}); } }
stream流属于管道流,只能被消费一次,第一个stream流调用完毕方法,数据就会流转到下一个stream上,而这时第一个stream流已经使用完毕,就会关闭,所以第一个stream就不能再调用方法了
map方法
如果需要将流中的元素映射到另一个流中,可以使用map方法,该方法的参数需要一个function函数式接口参数,可以将当流中的t类型转换为另一个r类型的流
function中的抽象方法: r apply(t t);
import java.util.stream.*; public class streammap{ public static void main(string[] args){ stream<string> stream1 = stream.of("1","2","3","4","5"); //把字符串类型的stream转换成integer类型的stream //可以使用map方法 stream<integer> stream2 = stream1.map((string s)->{ //使用integer类的方法parseint把每一个元素变成integer类型 return integer.parseint(s); }); stream2.foreach((integer)->{system.out.println(integer);}); } }
count方法
import java.util.stream.*; import java.util.*; //用来统计stream流中的元素个数 //count方法是一个终结方法,使用该方法后,该流不能再调用其他方法 public class countdemo{ public static void main(string[] args){ arraylist<integer> list = new arraylist<>(); for(int i=0;i<=5;i++){ list.add(i); } //获取stream stream<integer> stream = list.stream(); //统计list集合的元素有几个 long count = stream.count(); system.out.println(count); } }
limit截取方法
import java.util.stream.*; class streamlimit{ public static void main(string[] args){ string[] arr={"美羊羊","喜羊羊","懒羊羊","灰太狼","红太狼"}; stream<string> stream = stream.of(arr); //使用limit对stream流中元素截取 stream<string> stream2 = stream.limit(3); stream2.foreach((n)->{system.out.println(n);}); } /* 美羊羊 喜羊羊 懒羊羊 */ }
skip跳过指定元素方法
import java.util.stream.*; class streamlimit{ public static void main(string[] args){ string[] arr={"美羊羊","喜羊羊","懒羊羊","灰太狼","红太狼"}; stream<string> stream = stream.of(arr); //使用skipt对stream流中元素进行跳过 stream<string> stream2 = stream.skip(3); stream2.foreach((n)->{system.out.println(n);}); } }
concat方法,可以把流组合在一起
import java.util.stream.*; import java.util.*; public class streamconcat{ public static void main(string[] args){ stream<string> stream1 = stream.of("魔术师","科比","詹姆斯","邓肯","奥尼尔"); stream<string> stream2 = stream.of("基德","乔丹","皮蓬","诺维斯基","穆大叔"); //把两个流组合在一起 stream<string> concat = stream.concat(stream1,stream2); concat.foreach((name)->{ system.out.println(new random().nextint(100)+"号"+name); }); } }
练习
import java.util.stream.*; import java.util.*; public class streamtest{ public static void main(string[] args){ //第一只队伍 arraylist<string> one = new arraylist<>(); one.add("迪丽热巴"); one.add("宋远桥"); one.add("苏星河"); one.add("石破天"); one.add("石中玉"); one.add("老子"); one.add("庄子"); one.add("洪七公"); //调用方法stream转换成stream流 stream<string> onestream = one.stream(); //过滤 把名字长度为3的返回给新的流 stream<string> newstream = onestream.filter((string name)->{return name.length()==3;}); //过滤,只要前面三个 stream<string> new2stream = newstream.limit(3); //第二只队伍 arraylist<string> two = new arraylist<>(); two.add("古力娜扎"); two.add("张无忌"); two.add("赵丽颖"); two.add("张三丰"); two.add("尼古拉斯赵四"); two.add("张天爱"); two.add("张二狗"); //创建流 stream<string> twostream = two.stream(); //只要姓张的 stream<string> s1 =twostream.filter((string name)->{return name.startswith("张");}); //不要前面两个,使用跳过方法 stream<string> s2 = s1.skip(2); //组合两个流,合并在一起 stream<string> s3 = stream.concat(new2stream,s2); s3.map(name->new person(name)).foreach(p->system.out.println(p)); } }
方法引用
通过对象名来引用成员方法
通过对象名引用成员方法
使用前提是对象名是已经存在的,成员方法也是已经存在,就可以使用对象名来引用成员方法
public interface printable{ public abstract void print(string s); }
public class methodrerobject{ public void printuppercasestring(string str){ system.out.println(str.touppercase()); } }
public class objectmethodreference{ //定义一个方法,方法的参数传递printable接口 public static void printstring(printable p){ p.print("hello"); } public static void main(string[] args){ printstring((s)->{ //创建methodrerobject对象 methodrerobject obj = new methodrerobject(); // obj.printuppercasestring(s); }); //使用方法引用优化lambda //对象是已经存在的,成员方法也是已经存在的methodrerobject //所以我们可以使用对象名引用成员方法printuppercasestring methodrerobject obj = new methodrerobject(); printstring(obj::printuppercasestring); } }
通过类名引用静态成员方法
public interface calcable{ //该接口用于实现获取一个绝对值 //接口要实现的功能在lambda表达式里实现了 public abstract int calsabs(int number); }
public class staticmethodreference{ public static int method(int number,calcable c){ return c.calsabs(number); } public static void main(string[] args){ //使用lambda表达式来实现一个绝对值 int number = method(-10,(n)->{ //使用类math的方法获取绝对值,实现接口功能 return math.abs(n); }); system.out.println(number); //使用方法引用优化lambda表达式 //math类是存在的 //abs计算绝对值的静态方法也是存在的,所以可以通过类名引用静态方法 int number2 = method(-10,math::abs); system.out.println(number2); } }
super引用父类的成员方法
public class human{ public void sayhello(){ system.out.println("hello 我是human"); } }
public interface greetable{ public abstract void greet(); }
public class man extends human{ public void sayhello(){ system.out.println("hello 我是man"); } public void method(greetable g){ g.greet(); } public void show(){ method(()->{ human h = new human(); h.sayhello(); }); method(()->{ super.sayhello(); }); method(super::sayhello); } public static void main(string[] args){ new man().show(); } }
this引用本类的成员方法
public interface richable{ public abstract void buy(); }
public class husband{ public void buyhouse(){ system.out.println("北京二环内买一套四合院"); } public void marry(richable r){ r.buy(); } public void shhappay(){ marry(()->{ this.buyhouse(); }); marry(this::buyhouse); } public static void main(string[] args){ new husband().shhappay(); } }
类的构造器引用
public class person{ private string name; public person(){} public person(string name ){ this.name=name; } public void setname(string name){ this.name=name; } public string getname(){ return name; } public string tostring(){ return "姓名"+name; } }
public interface personbuilder { //根据名字返回person类型 public abstract person builderperson(string name); }
public class demo { public static void printname(string name,personbuilder pb){ //传我一个姓名,返回一个person对象 person person = pb.builderperson(name); system.out.println(person.getname()); } //构造方法是已知的 //创建对象是已知的 public static void main(string[] args){ printname("迪丽热巴",(string name)->{ return new person(name); }); printname("古力娜扎",person::new); } }
数组的构造器引用
public interface arraybuilder { public abstract int[] builderarray(int length); }
import java.util.arrays; public class demo1 { public static int[] createarray(int length,arraybuilder ab){ return ab.builderarray(length); } public static void main(string[] args) { int[] arr1=createarray(10,(len)->{ return new int[len]; }); system.out.println(arr1.length); int[] arr2 = createarray(10,int[]::new); system.out.println(arrays.tostring(arr2)); system.out.println(arr2.length); } }