java8-02-Stream-API

[TOC]

0 Stream簡介

  • 家庭住址 :java.util.stream.Stream<T>

  • 出生年月:Java8問世的時候他就來到了世上

  • 主要技能:那可以吹上三天三夜了……

  • 主要特征

    • 不改變輸入源

    • 中間的各種操作是lazy的(惰性求值、延遲操作)

    • 只有當開始消費流的時候,流才有意義

    • 隱式迭代

  • ……

總體感覺,Stream相當于一個進化版的Iterator。Java8源碼里是這么注釋的:

A sequence of elements supporting sequential and parallel aggregate operations

可以方便的對集合進行遍歷、過濾、映射、匯聚、切片等復雜操作。最終匯聚成一個新的Stream,不改變原始數據。并且各種復雜的操作都是lazy的,也就是說會盡可能的將所有的中間操作在最終的匯聚操作一次性完成。

比起傳統的對象和數據的操作,Stream更專注于對流的計算,和傳說中的函數式編程有點類似。

他具體進化的多牛逼,自己體驗吧。

給一組輸入數據:

List<Integer> list = Arrays.asList(1, null, 3, 1, null, 4, 5, null, 2, 0);

求輸入序列中非空奇數之和,并且相同奇數算作同一個。

  • 在lambda還在娘胎里的時候,為了實現這個功能,可能會這么做

int s = 0;
// 先放在Set里去重
Set<Integer> set = new HashSet<>(list);
for (Integer i : set) {if (i != null && (i & 1) == 0) {s += i;}
}
System.out.println(s);
  • lambdaStream雙劍合璧之后:

int sum = list.stream().filter(e -> e != null && (e & 1) == 1).distinct().mapToInt(i -> i).sum();

1 獲取Stream

  • 從lambda的其他好基友那里獲取Stream

從1.8開始,接口中也可以存在 default 修飾的方法了。

java.util.Collection<E> 中有如下聲明:

public interface Collection<E> extends Iterable<E> {// 獲取普通的流default Stream<E> stream() {return StreamSupport.stream(spliterator(), false);}// 獲取并行流default Stream<E> parallelStream() {return StreamSupport.stream(spliterator(), true);}
}

java.util.Arrays中有如下聲明:

    public static <T> Stream<T> stream(T[] array) {return stream(array, 0, array.length);}public static IntStream stream(int[] array) {return stream(array, 0, array.length);}// 其他類似的方法不再一一列出

示例

List<String> strs = Arrays.asList("apache", "spark");
Stream<String> stringStream = strs.stream();IntStream intStream = Arrays.stream(new int[] { 1, 25, 4, 2 });
  • 通過Stream接口獲取

Stream<String> stream = Stream.of("hello", "world");
Stream<String> stream2 = Stream.of("haha");
Stream<HouseInfo> stream3 = Stream.of(new HouseInfo[] { new HouseInfo(), new HouseInfo() });Stream<Integer> stream4 = Stream.iterate(1, i -> 2 * i + 1);Stream<Double> stream5 = Stream.generate(() -> Math.random());

注意:Stream.iterate()Stream.generate()生成的是無限流,一般要手動limit

2 轉換Stream

流過濾、流切片

這部分相對來說還算簡單明了,看個例子就夠了

// 獲取流
Stream<String> stream = Stream.of(//null, "apache", null, "apache", "apache", //"github", "docker", "java", //"hadoop", "linux", "spark", "alifafa");stream// 去除null,保留包含a的字符串.filter(e -> e != null && e.contains("a"))//.distinct()// 去重,當然要有equals()和hashCode()方法支持了.limit(3)// 只取滿足條件的前三個.forEach(System.out::println);// 消費流

map/flatMap

Stream的map定義如下:

<R> Stream<R> map(Function<? super T, ? extends R> mapper);

也就是說,接收一個輸入(T:當前正在迭代的元素),輸出另一種類型(R)。

Stream.of(null, "apache", null, "apache", "apache", //"hadoop", "linux", "spark", "alifafa")//.filter(e -> e != null && e.length() > 0)//.map(str -> str.charAt(0))//取出第一個字符.forEach(System.out::println);

sorted

排序也比較直觀,有兩種:

// 按照元素的Comparable接口的實現來排序
Stream<T> sorted();// 指定Comparator來自定義排序
Stream<T> sorted(Comparator<? super T> comparator);

示例:

List<HouseInfo> houseInfos = Lists.newArrayList(//new HouseInfo(1, "恒大星級公寓", 100, 1), //new HouseInfo(2, "匯智湖畔", 999, 2), //new HouseInfo(3, "張江湯臣豪園", 100, 1), //new HouseInfo(4, "保利星苑", 23, 10), //new HouseInfo(5, "北顧小區", 66, 23), //new HouseInfo(6, "北杰公寓", null, 55), //new HouseInfo(7, "保利星苑", 77, 66), //new HouseInfo(8, "保利星苑", 111, 12)//
);houseInfos.stream().sorted((h1, h2) -> {if (h1 == null || h2 == null)return 0;if (h1.getDistance() == null || h2.getDistance() == null)return 0;int ret = h1.getDistance().compareTo(h2.getDistance());if (ret == 0) {if (h1.getBrowseCount() == null || h2.getBrowseCount() == null)return 0;return h1.getBrowseCount().compareTo(h2.getBrowseCount());}return ret;
});

3 終止/消費Stream

條件測試、初級統計操作

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);// 是不是所有元素都大于零
System.out.println(list.stream().allMatch(e -> e > 0));
// 是不是存在偶數
System.out.println(list.stream().anyMatch(e -> (e & 1) == 0));
// 是不是都不小于零
System.out.println(list.stream().noneMatch(e -> e < 0));// 找出第一個大于等于4的元素
Optional<Integer> optional = list.stream().filter(e -> e >= 4).findFirst();
// 如果存在的話,就執行ifPresent中指定的操作
optional.ifPresent(System.out::println);// 大于等于4的元素的個數
System.out.println(list.stream().filter(e -> e >= 4).count());
// 獲取最小的
System.out.println(list.stream().min(Integer::compareTo));
// 獲取最大的
System.out.println(list.stream().max(Integer::compareTo));
// 先轉換成IntStream,max就不需要比較器了
System.out.println(list.stream().mapToInt(i -> i).max());

reduce

這個詞不知道怎么翻譯,有人翻譯為 規約匯聚

反正就是將經過一系列轉換后的流中的數據最終收集起來,收集的同時可能會反復 apply 某個 reduce函數

reduce()方法有以下兩個重載的變體:

// 返回的不是Optional,因為正常情況下至少有參數identity可以保證返回值不會為null
T reduce(T identity, BinaryOperator<T> accumulator);<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner);

示例:

// 遍歷元素,反復apply (i,j)->i+j的操作
Integer reduce = Stream.iterate(1, i -> i + 1)//1,2,3,...,10,....limit(10)//.reduce(0, (i, j) -> i + j);//55Optional<Integer> reduce2 = Stream.iterate(1, i -> i + 1)//.limit(10)//.reduce((i, j) -> i + j);

collect

該操作很好理解,顧名思義就是將Stream中的元素collect到一個地方。

  • 最常規(最不常用)的collect方法

// 最牛逼的往往是最不常用的,畢竟這個方法理解起來太過復雜了
<R> R collect(Supplier<R> supplier,BiConsumer<R, ? super T> accumulator,BiConsumer<R, R> combiner);
// 至于這個方法的參數含義,請看下面的例子
  • 一個參數的版本

<R, A> R collect(Collector<? super T, A, R> collector);

Collector接口(他不是函數式接口,沒法使用lambda)的關鍵代碼如下:

public interface Collector<T, A, R> {/****/Supplier<A> supplier();/*** */BiConsumer<A, T> accumulator();/*** */BinaryOperator<A> combiner();/****/Function<A, R> finisher();/*** */Set<Characteristics> characteristics();}

先來看一個關于三個參數的collect()方法的例子,除非特殊情況,不然我保證你看了之后這輩子都不想用它……

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
ArrayList<Integer> ret1 = numbers.stream()//.map(i -> i * 2)// 擴大兩倍.collect(//() -> new ArrayList<Integer>(), //參數1(list, e) -> list.add(e), //參數2(list1, list2) -> list1.addAll(list2)//參數3
);/**** <pre>* collect()方法的三個參數解釋如下:* 1. () -> new ArrayList<Integer>() *         生成一個新的用來存儲結果的集合* 2. (list, e) -> list.add(e)*         list:是參數1中生成的新集合*         e:是Stream中正在被迭代的當前元素*         該參數的作用就是將元素添加到新生成的集合中* 3. (list1, list2) -> list1.addAll(list2)*         合并集合* </pre>***/ret1.forEach(System.out::println);

不使用lambda的時候,等價的代碼應該是這個樣子的……

List<Integer> ret3 = numbers.stream()//.map(i -> i * 2)// 擴大兩倍.collect(new Supplier<List<Integer>>() {@Overridepublic List<Integer> get() {// 只是為了提供一個集合來存儲元素return new ArrayList<>();}}, new BiConsumer<List<Integer>, Integer>() {@Overridepublic void accept(List<Integer> list, Integer e) {// 將當前元素添加至第一個參數返回的容器中list.add(e);}}, new BiConsumer<List<Integer>, List<Integer>>() {@Overridepublic void accept(List<Integer> list1, List<Integer> list2) {// 合并容器list1.addAll(list2);}});ret3.forEach(System.out::println);

是不是被惡心到了……

同樣的,用Java調用spark的api的時候,如果沒有lambda的話,比上面的代碼還惡心……

順便打個免費的廣告,可以看看本大俠這篇使用各種版本實現的Spark的HelloWorld: http://blog.csdn.net/hylexus/...,來證明一下有lambda的世界是有多么幸福……

不過,當你理解了三個參數的collect方法之后,可以使用構造器引用和方法引用來使代碼更簡潔:

ArrayList<Integer> ret2 = numbers.stream()//.map(i -> i * 2)// 擴大兩倍.collect(//ArrayList::new, //List::add, //List::addAll//
);ret2.forEach(System.out::println);

Collectors工具的使用(高級統計操作)

上面的三個和一個參數的collect()方法都異常復雜,最常用的還是一個參數的版本。但是那個Collector自己實現的話還是很惡心。

還好,常用的Collect操作對應的Collector都在java.util.stream.Collectors 中提供了。很強大的工具……

以下示例都是對該list的操作:

List<HouseInfo> houseInfos = Lists.newArrayList(//new HouseInfo(1, "恒大星級公寓", 100, 1), // 小區ID,小區名,瀏覽數,距離new HouseInfo(2, "匯智湖畔", 999, 2), //new HouseInfo(3, "張江湯臣豪園", 100, 1), //new HouseInfo(4, "保利星苑", 111, 10), //new HouseInfo(5, "北顧小區", 66, 23), //new HouseInfo(6, "北杰公寓", 77, 55), //new HouseInfo(7, "保利星苑", 77, 66), //new HouseInfo(8, "保利星苑", 111, 12)//
);

好了,開始裝逼之旅 ^_^ ……

  • 提取小區名

// 獲取所有小區名,放到list中
List<String> ret1 = houseInfos.stream().map(HouseInfo::getHouseName).collect(Collectors.toList());
ret1.forEach(System.out::println);// 獲取所有的小區名,放到set中去重
// 當然也可先distinct()再collect到List中
Set<String> ret2 = houseInfos.stream().map(HouseInfo::getHouseName).collect(Collectors.toSet());
ret2.forEach(System.out::println);// 將所有的小區名用_^_連接起來
// 恒大星級公寓_^_匯智湖畔_^_張江湯臣豪園_^_保利星苑_^_北顧小區_^_北杰公寓_^_保利星苑_^_保利星苑
String names = houseInfos.stream().map(HouseInfo::getHouseName).collect(Collectors.joining("_^_"));
System.out.println(names);// 指定集合類型為ArrayList
ArrayList<String> collect = houseInfos.stream().map(HouseInfo::getHouseName).collect(Collectors.toCollection(ArrayList::new));
  • 最值

// 獲取瀏覽數最高的小區
Optional<HouseInfo> ret3 = houseInfos.stream()//.filter(h -> h.getBrowseCount() != null)// 過濾掉瀏覽數為空的.collect(Collectors.maxBy((h1, h2) -> Integer.compare(h1.getBrowseCount(), h2.getBrowseCount())));
System.out.println(ret3.get());// 獲取最高瀏覽數
Optional<Integer> ret4 = houseInfos.stream()//.filter(h -> h.getBrowseCount() != null)// 去掉瀏覽數為空的.map(HouseInfo::getBrowseCount)// 取出瀏覽數.collect(Collectors.maxBy(Integer::compare));// 方法引用,比較瀏覽數
System.out.println(ret4.get());
  • 總數、總和

// 獲取總數
// 其實這個操作直接用houseInfos.size()就可以了,此處僅為演示語法
Long total = houseInfos.stream().collect(Collectors.counting());
System.out.println(total);// 瀏覽數總和
Integer ret5 = houseInfos.stream()//.filter(h -> h.getBrowseCount() != null)// 過濾掉瀏覽數為空的.collect(Collectors.summingInt(HouseInfo::getBrowseCount));
System.out.println(ret5);// 瀏覽數總和
Integer ret6 = houseInfos.stream()//.filter(h -> h.getBrowseCount() != null)// 過濾掉瀏覽數為空的.map(HouseInfo::getBrowseCount).collect(Collectors.summingInt(i -> i));
System.out.println(ret6);// 瀏覽數總和
int ret7 = houseInfos.stream()//.filter(h -> h.getBrowseCount() != null)// 過濾掉瀏覽數為空的.mapToInt(HouseInfo::getBrowseCount)// 先轉換為IntStream后直接用其sum()方法.sum();
System.out.println(ret7);
  • 均值

// 瀏覽數平均值
Double ret8 = houseInfos.stream()//.filter(h -> h.getBrowseCount() != null)// 過濾掉瀏覽數為空的.collect(Collectors.averagingDouble(HouseInfo::getBrowseCount));
System.out.println(ret8);// 瀏覽數平均值
OptionalDouble ret9 = houseInfos.stream()//.filter(h -> h.getBrowseCount() != null)// 過濾掉瀏覽數為空的.mapToDouble(HouseInfo::getBrowseCount)// 先轉換為DoubleStream后直接用其average()方法.average();
System.out.println(ret9.getAsDouble());
  • 統計信息

// 獲取統計信息
DoubleSummaryStatistics statistics = houseInfos.stream()//.filter(h -> h.getBrowseCount() != null).collect(Collectors.summarizingDouble(HouseInfo::getBrowseCount));
System.out.println("avg:" + statistics.getAverage());
System.out.println("max:" + statistics.getMax());
System.out.println("sum:" + statistics.getSum());
  • 分組

// 按瀏覽數分組
Map<Integer, List<HouseInfo>> ret10 = houseInfos.stream()//.filter(h -> h.getBrowseCount() != null)// 過濾掉瀏覽數為空的.collect(Collectors.groupingBy(HouseInfo::getBrowseCount));
ret10.forEach((count, house) -> {System.out.println("BrowseCount:" + count + " " + house);
});// 多級分組
// 先按瀏覽數分組,二級分組用距離分組
Map<Integer, Map<String, List<HouseInfo>>> ret11 = houseInfos.stream()//.filter(h -> h.getBrowseCount() != null && h.getDistance() != null)//.collect(Collectors.groupingBy(HouseInfo::getBrowseCount,Collectors.groupingBy((HouseInfo h) -> {if (h.getDistance() <= 10)return "較近";else if (h.getDistance() <= 20)return "近";return "較遠";})));//結果大概長這樣
ret11.forEach((count, v) -> {System.out.println("瀏覽數:" + count);v.forEach((desc, houses) -> {System.out.println("\t" + desc);houses.forEach(h -> System.out.println("\t\t" + h));});
});
/***** <pre>*  瀏覽數:66較遠HouseInfo [houseId=5, houseName=北顧小區, browseCount=66, distance=23]瀏覽數:100較近HouseInfo [houseId=1, houseName=恒大星級公寓, browseCount=100, distance=1]HouseInfo [houseId=3, houseName=張江湯臣豪園, browseCount=100, distance=1]瀏覽數:999較近HouseInfo [houseId=2, houseName=匯智湖畔, browseCount=999, distance=2]瀏覽數:77較遠HouseInfo [houseId=6, houseName=北杰公寓, browseCount=77, distance=55]HouseInfo [houseId=7, houseName=保利星苑, browseCount=77, distance=66]瀏覽數:111近HouseInfo [houseId=8, houseName=保利星苑, browseCount=111, distance=12]較近HouseInfo [houseId=4, houseName=保利星苑, browseCount=111, distance=10]* * </pre>* ****/
  • 分區

// 按距離分區(兩部分)
Map<Boolean, List<HouseInfo>> ret12 = houseInfos.stream()//.filter(h -> h.getDistance() != null)//.collect(Collectors.partitioningBy(h -> h.getDistance() <= 20));
/***** <pre>*  較遠HouseInfo [houseId=5, houseName=北顧小區, browseCount=66, distance=23]HouseInfo [houseId=6, houseName=北杰公寓, browseCount=77, distance=55]HouseInfo [houseId=7, houseName=保利星苑, browseCount=77, distance=66]較近HouseInfo [houseId=1, houseName=恒大星級公寓, browseCount=100, distance=1]HouseInfo [houseId=2, houseName=匯智湖畔, browseCount=999, distance=2]HouseInfo [houseId=3, houseName=張江湯臣豪園, browseCount=100, distance=1]HouseInfo [houseId=4, houseName=保利星苑, browseCount=111, distance=10]HouseInfo [houseId=8, houseName=保利星苑, browseCount=111, distance=12]* * </pre>****/
ret12.forEach((t, houses) -> {System.out.println(t ? "較近" : "較遠");houses.forEach(h -> System.out.println("\t\t" + h));
});Map<Boolean, Map<Boolean, List<HouseInfo>>> ret13 = houseInfos.stream()//.filter(h -> h.getDistance() != null)//.collect(Collectors.partitioningBy(h -> h.getDistance() <= 20,Collectors.partitioningBy(h -> h.getBrowseCount() >= 70))
);/****** <pre>*  較遠瀏覽較少HouseInfo [houseId=5, houseName=北顧小區, browseCount=66, distance=23]瀏覽較多HouseInfo [houseId=6, houseName=北杰公寓, browseCount=77, distance=55]HouseInfo [houseId=7, houseName=保利星苑, browseCount=77, distance=66]較近瀏覽較少瀏覽較多HouseInfo [houseId=1, houseName=恒大星級公寓, browseCount=100, distance=1]HouseInfo [houseId=2, houseName=匯智湖畔, browseCount=999, distance=2]HouseInfo [houseId=3, houseName=張江湯臣豪園, browseCount=100, distance=1]HouseInfo [houseId=4, houseName=保利星苑, browseCount=111, distance=10]HouseInfo [houseId=8, houseName=保利星苑, browseCount=111, distance=12]* </pre>****/ret13.forEach((less, value) -> {System.out.println(less ? "較近" : "較遠");value.forEach((moreCount, houses) -> {System.out.println(moreCount ? "\t瀏覽較多" : "\t瀏覽較少");houses.forEach(h -> System.out.println("\t\t" + h));});
});

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/540884.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/540884.shtml
英文地址,請注明出處:http://en.pswp.cn/news/540884.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

跟隨者數字解碼_跟隨模式的數字

跟隨者數字解碼Problem statement: 問題陳述&#xff1a; Given a pattern containing only Is and Ds. I stands for increasing and D for decreasing. Devise an algorithm to print the minimum number following that pattern. Digits are from 1-9 and digits cant repe…

Linux內核機器ID,linux-如何強制內核重新讀取/重新初始化PCI設備ID?

我的機器(正在運行Linux內核3.2.38的計算機)在引導時具有錯誤的PCI設備的子系統ID(子設備和子供應商ID).如果我然后在系統仍處于啟動狀態(即熱插拔)時物理地拔出PCI設備并重新插入,則它將獲得正確的ID.請注意,錯誤的子設備ID和子供應商ID與設備的設備ID和供應商ID相同(請參見下…

Android ImageButton示例代碼

1) XML File: activity_main 1)XML文件&#xff1a;activity_main <?xml version"1.0" encoding"utf-8"?><android.support.constraint.ConstraintLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"…

IIS 偽靜態下 利用PHP獲取 網址后綴

$_SERVER[HTTP_X_ORIGINAL_URL];轉載于:https://www.cnblogs.com/paddygege/p/7238228.html

kotlin 小數位數_Kotlin程序生成4位數OTP

kotlin 小數位數OTP stands for "One Time Password" is a 4-8 digit alphanumeric code which is sent to the user via email or phone number for validation. As the name suggests, it can be used once only. OTP代表“ 一次密碼”&#xff0c;它是4-8位的字母…

NestedScrolling機制

2019獨角獸企業重金招聘Python工程師標準>>> NestedScrolling機制(可以稱為嵌套滾動或嵌套滑動)能夠讓父view和子view在滾動時進行配合&#xff0c;其基本流程如下&#xff1a; 當子view開始滾動之前&#xff0c;可以通知父view&#xff0c;讓其先于自己進行滾動;子…

linux重定向命令是干嘛的,Linux系統下重定向命令應用及其語法有什么?

1。 標準輸入的控制語法&#xff1a;命令 文件將命令的執行結果送至指定的文件中。例如&#xff1a;ls -l > list 將執行“ls -l” 命令的結果寫入文件list 中。語法&#xff1a;命令>&#xff01; 文件將命令的執行結果送至指定的文件中&#xff0c;若文件已經存在&…

kotlin 第一個程序_Kotlin程序減去兩個矩陣

kotlin 第一個程序Given two matrices, we have to subtract them. 給定兩個矩陣&#xff0c;我們必須將它們相減。 Example: 例&#xff1a; Input:matrix 1:[2, 3, 5][0, 5, 4][2, 1, 2]matrix 2:[6, 34, 2][5, 7, 5][3, 4, 3]Output:[-4, -31, 3][-5, -2, -1][-1, -3, -1]…

linux進程q是什么意思,Linux進程

#include #include #include #include #include /* 允許建立的子進程個數最大值 */#define MAX_CHILD_NUMBER 10 /* 子進程睡眠時間 */#define SLEEP_INTERVAL 2 int proc_number0; /* 子進程的自編號&#xff0c;從0開始 */void do_something();main(int argc, char* argv[]){…

cd-rom門鎖定什么意思_CD-ROM XA的完整格式是什么?

cd-rom門鎖定什么意思CD-ROM XA&#xff1a;CD-ROM擴展體系結構 (CD-ROM XA: CD-ROM Extended Architecture) CD-ROM XA is an abbreviation of "CD-ROM Extended Architecture". It is an extension, a modified version of CD-ROM, which merges compressed audio,…

linux服務chm,linux系統服務?chm

冒算發出喬家開具面霜&#xff1f;磨去開源新片米泉坎坷纜船六谷酷炫。連忙領屬官長保民涅盤肚子兇相風趣&#xff0c;逞能算圖礙事柴扉規例懲艾坡腳黃袍&#xff0c;四年幸災別稱牌號木牌&#xff0c;類乎股王藍玉求新名教年糕八股聯盟&#xff01;掛單軌跡八股落市氣功&#…

ImageView的scaleType詳解

1. 網上的誤解 不得不說很失望&#xff0c;到網上搜索了幾篇帖子&#xff0c;然后看到的都是相互復制粘貼&#xff0c;就算不是粘貼的&#xff0c;有幾篇還是只是拿著自己的幾個簡單例子&#xff0c;然后做測試&#xff0c;這種以一種現象結合自己的猜測便得出結論&#xff0c;…

IDBI的完整格式是什么?

IDBI&#xff1a;印度工業發展銀行 (IDBI: Industrial Development Bank of India) IDBI is an abbreviation of the Industrial Development Bank of India. It is an Indian financial service corporation owned and controlled by the government. In 1964, it was founded…

linux判斷內存并釋放,linux 內存清理/釋放命令

# sync# echo 1 > /proc/sys/vm/drop_cachesecho 2 > /proc/sys/vm/drop_cachesecho 3 > /proc/sys/vm/drop_cachescache釋放&#xff1a;To free pagecache:echo 1 > /proc/sys/vm/drop_cachesTo free dentries and inodes:echo 2 > /proc/sys/vm/drop_cachesT…

kei注釋_KEI的完整形式是什么?

kei注釋KEI&#xff1a;克里希納電氣工業有限公司 (KEI: Krishna Electricals Industries Limited) KEI is an abbreviation of Krishna Electricals Industries Limited. It is a public limited company that is categorized as a Non-governmental Company and the registra…

基于嵌入式linux的數碼相框的設計,基于Linux NFS的Web數碼相框設計

O 引言隨著數碼相機和互聯網的普及&#xff0c;越來越多的家庭擁有自己的媒體庫。媒體庫中既包含有自己拍攝的影像文件&#xff0c;也有從網絡上下載的影像資料。然而展示影像資料的手段單一&#xff0c;主要通過PC來實現。因此未來構建以媒體庫為中心的家庭多媒體網絡&#xf…

Spark學習

mapreduce RDD 流程示意 Yarn 轉載于:https://www.cnblogs.com/ecollab/p/7248306.html

CSS中的resize屬性

CSS | 調整屬性 (CSS | resize Property) Starting note: 開始說明&#xff1a; We deal with various elements regularly while we are developing a website or a web page and to organize, edit and format those elements is a very crucial task as those elements are…

Spring Boot + JPA + Freemarker 實現后端分頁 完整示例

Spring Boot JPA Freemarker 實現后端分頁 完整示例 界面效果 螢幕快照 2017-07-28 15.34.42.png螢幕快照 2017-07-28 15.34.26.png螢幕快照 2017-07-28 15.17.00.png螢幕快照 2017-07-28 15.16.09.png螢幕快照 2017-07-28 15.15.44.png前端代碼 <#-- 表格服務端分頁&…

物聯網網關linux帶串口,物聯網網關|串口轉HTTP GET協議

支持和Web服務器通信的物聯網網關發布時間&#xff1a;2017-05-10作者&#xff1a;上海卓嵐瀏覽量&#xff1a;55821.概述隨著物聯網的發展&#xff0c;越來越多的設備需要連接到云端。其中的設備有各類儀表、工業設備、采集設備、傳感器&#xff0c;這些設備都以串口(RS232、R…