Stream是一類用於替代對集合操做的工具類+Lambda式編程,他能夠替代現有的遍歷、過濾、求和、求最值、排序、轉換等
@Test public void stream() { //操做List List<Map<String, String>> mapList = new ArrayList() { { Map<String, String> m = new HashMap(); m.put("a", "1"); Map<String, String> m2 = new HashMap(); m2.put("b", "2"); add(m); add(m2); } }; mapList.stream().forEach(item-> System.out.println(item)); //操做Map Map<String,Object> mp = new HashMap(){ { put("a","1"); put("b","2"); put("c","3"); put("d","4"); } }; mp.keySet().stream().forEachOrdered(item-> System.out.println(mp.get(item))); }
List<Integer> mapList = new ArrayList() { { add(1); add(10); add(12); add(33); add(99); } }; //mapList.stream().forEach(item-> System.out.println(item)); mapList = mapList.stream().filter(item->{ return item>30; }).collect(Collectors.toList()); System.out.println(mapList);
轉換map和極值編程
@Test public void trans(){ List<Person> ps = new ArrayList<Person>(){ { Person p1 = new Person(); p1.setAge(11); p1.setName("張強"); Person p2 = new Person(); p2.setAge(17); p2.setName("李思"); Person p3 = new Person(); p3.setAge(20); p3.setName("John"); add(p1); add(p2); add(p3); } }; //取出全部age字段爲一個List List<Integer> sumAge = ps.stream().map(Person::getAge).collect(Collectors.toList()); System.out.println(sumAge); //取出age最大的那 Integer maxAge =sumAge.stream().max(Integer::compare).get(); System.out.println(maxAge); } class Person{ private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
class Person{ private String name; private int age; private Date joinDate; private String label; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Date getJoinDate() { return joinDate; } public void setJoinDate(Date joinDate) { this.joinDate = joinDate; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public class DataLoopTest { private static final Logger LOG= LoggerFactory.getLogger(DataLoopTest.class); private static final List<Person> persons = new ArrayList<>(); static { for(int i=0;i<=1000000;i++){ Person p = new Person(); p.setAge(i); p.setName("zhangSan"); p.setJoinDate(new Date()); persons.add(p); } } /** * for 循環耗時 ===> 1.988 * for 循環耗時 ===> 2.198 * for 循環耗時 ===> 1.978 * */ @Test public void forTest(){ Instant date_start = Instant.now(); int personSize = persons.size(); for(int i=0;i<personSize;i++){ persons.get(i).setLabel(persons.get(i).getName().concat("-"+persons.get(i).getAge()).concat("-"+persons.get(i).getJoinDate().getTime())); } Instant date_end = Instant.now(); LOG.info("for 循環耗時 ===> {}", Duration.between(date_start,date_end).toMillis()/1000.0); } /** * forEach 循環耗時 ===> 1.607 * forEach 循環耗時 ===> 2.242 * forEach 循環耗時 ===> 1.875 */ @Test public void forEach(){ Instant date_start = Instant.now(); for(Person p:persons){ p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime())); } Instant date_end = Instant.now(); LOG.info("forEach 循環耗時 ===> {}", Duration.between(date_start,date_end).toMillis()/1000.0); } /** * streamForeach 循環耗時 ===> 1.972 * streamForeach 循環耗時 ===> 1.969 * streamForeach 循環耗時 ===> 2.125 */ @Test public void streamForeach(){ Instant date_start = Instant.now(); persons.stream().forEach(p->p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime()))); Instant date_end = Instant.now(); LOG.info("streamForeach 循環耗時 ===> {}", Duration.between(date_start,date_end).toMillis()/1000.0); } /** * parallelStreamForeach 循環耗時 ===> 1.897 * parallelStreamForeach 循環耗時 ===> 1.942 * parallelStreamForeach 循環耗時 ===> 1.642 */ @Test public void parallelStreamForeach(){ Instant date_start = Instant.now(); persons.parallelStream().forEach(p->p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime()))); Instant date_end = Instant.now(); LOG.info("parallelStreamForeach 循環耗時 ===> {}", Duration.between(date_start,date_end).toMillis()/1000.0); } }
public class DataLoopBlockTest { private static final Logger LOG= LoggerFactory.getLogger(DataLoopTest.class); private static final List<Person> persons = new ArrayList<>(); static { for(int i=0;i<=100000;i++){ Person p = new Person(); p.setAge(i); p.setName("zhangSan"); p.setJoinDate(new Date()); persons.add(p); } } /** * for 循環耗時 ===> 101.385 * for 循環耗時 ===> 102.161 * for 循環耗時 ===> 101.472 * */ @Test public void forTest(){ Instant date_start = Instant.now(); int personSize = persons.size(); for(int i=0;i<personSize;i++){ try { Thread.sleep(1); persons.get(i).setLabel(persons.get(i).getName().concat("-"+persons.get(i).getAge()).concat("-"+persons.get(i).getJoinDate().getTime())); }catch (Exception e){ e.printStackTrace(); } } Instant date_end = Instant.now(); LOG.info("for 循環耗時 ===> {}", Duration.between(date_start,date_end).toMillis()/1000.0); } /** * forEach 循環耗時 ===> 101.027 * forEach 循環耗時 ===> 102.488 * forEach 循環耗時 ===> 101.608 */ @Test public void forEach(){ Instant date_start = Instant.now(); for(Person p:persons){ try { Thread.sleep(1); p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime())); }catch (Exception e){ e.printStackTrace(); } } Instant date_end = Instant.now(); LOG.info("forEach 循環耗時 ===> {}", Duration.between(date_start,date_end).toMillis()/1000.0); } /** * streamForeach 循環耗時 ===> 103.246 * streamForeach 循環耗時 ===> 101.128 * streamForeach 循環耗時 ===> 102.615 */ @Test public void streamForeach(){ Instant date_start = Instant.now(); //persons.stream().forEach(p->p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime()))); persons.stream().forEach(p->{ try { Thread.sleep(1); p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime())); }catch (Exception e){ e.printStackTrace(); } }); Instant date_end = Instant.now(); LOG.info("streamForeach 循環耗時 ===> {}", Duration.between(date_start,date_end).toMillis()/1000.0); } /** * parallelStreamForeach 循環耗時 ===> 51.391 * parallelStreamForeach 循環耗時 ===> 53.509 * parallelStreamForeach 循環耗時 ===> 50.831 */ @Test public void parallelStreamForeach(){ Instant date_start = Instant.now(); //persons.parallelStream().forEach(p->p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime()))); persons.parallelStream().forEach(p->{ try { Thread.sleep(1); p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime())); }catch (Exception e){ e.printStackTrace(); } }); Instant date_end = Instant.now(); LOG.info("parallelStreamForeach 循環耗時 ===> {}", Duration.between(date_start,date_end).toMillis()/1000.0); //LOG.info("\r\n===> {}",JSON.toJSONString(persons.get(10000))); } }
能夠看到在<s>百萬數據</s>下作簡單數據循環處理,對於普通for(for\foreach)循環或stream(並行、非並行)下,幾者的效率差別並不明顯, 注意: 在百萬數據下,普通for、foreach循環處理可能比stream的方式快許多,對於這點效率的損耗,其實lambda表達式對代碼的簡化更大! 另外,在並行流的循環下速度提高了一倍之多,當單個循環耗時較多時,會拉大與前幾者的循環效率 (以上測試僅對於循環而言,其餘類型業務處理,好比排序、求和、最大值等未作測試,我的猜想與以上測試結果類似)
persons.parallelStream().forEach(p->p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime())));
persons.parallelStream().forEach(p->{ try { Thread.sleep(1); p.setLabel(p.getName().concat("-"+p.getAge()).concat("-"+p.getJoinDate().getTime())); }catch (Exception e){ e.printStackTrace(); } });