java8 stream - map 與 flatMap

map和faltMap的共同點和區別

共同點

  • 都是依賴FuncX(入參,返回值)進行轉換(將一個類型依據程序邏輯轉換成另一種類型,根據入參和返回值)
  • 都能在轉換後直接被subscribe

區別

  • map返回的是結果集,flatmap返回的是包含結果集的Observable(返回結果不同)
  • map被訂閱時每傳遞一個事件執行一次onNext方法,flatmap多用於多對多,一對多,再被轉化爲多個時,一般利用from/just進行一一分發,被訂閱時將所有數據傳遞完畢彙總到一個Observable然後一一執行onNext方法(執行順序不同)>>>>(如單純用於一對一轉換則和map相同)
  • map只能單一轉換,單一隻的是隻能一對一進行轉換,指一個對象可以轉化爲另一個對象但是不能轉換成對象數組(map返回結果集不能直接使用from/just再次進行事件分發,一旦轉換成對象數組的話,再處理集合/數組的結果時需要利用for一一遍歷取出,而使用RxJava就是爲了剔除這樣的嵌套結構,使得整體的邏輯性更強。)
  • flatmap既可以單一轉換也可以一對多/多對多轉換,flatmap要求返回Observable,因此可以再內部進行from/just的再次事件分發,一一取出單一對象(轉換對象的能力不同)

代碼演示

/**
 * 
 */
package demo.test;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author sunkai
 *
 */
public class MapTest {

	static Function<Map<?, ?>, List<?>> flatMapFn = m -> {
		return m.values()//
				.stream() //
				.flatMap(it -> {

					Object[] objs;
					if (it instanceof Map) {
						// 遞歸
						objs = MapTest.flatMapFn.apply((Map<?, ?>) it).toArray();
					} else {
						objs = new Object[] { it };
					}

					return Arrays.stream(objs);
				}).collect(Collectors.toList());
	};

	public static void main(String... strings) {
		var words = new String[] { "Hello", "World" };

		// map得到結果: [ [H,e,l,o] , [W,o,r,l,d] ]
		var list = Arrays.asList(words).stream()//
				.map(w -> w.split("")) //
				.distinct()//
				.collect(Collectors.toList());

		System.out.println(list);

		// map得到結果: [H, e, l, o, W, r, d]
		var list2 = Arrays.asList(words).stream()//
				.map(w -> w.split("")) //
				.flatMap(w -> Arrays.stream(w)) // 對結果進行展開
				.distinct()//
				.collect(Collectors.toList());

		System.out.println(list2);

		// 簡化 list2
		var list3 = Arrays.asList(words).stream()//
				.flatMap(s -> Arrays.stream(s.split("")))// 將上面split拆分的方法放在此處
				.distinct()//
				.collect(Collectors.toList());

		System.out.println(list3);

		// 獲取Map中的所有value

		@SuppressWarnings("serial")
		Map<String, Object> root = new HashMap<>() {
			{
				put("k1", "var1");
				put("k2", new HashMap<>() {
					{
						put("k2_1", "var2_1");
						put("k2_2", "var2_2");
						put("k2_3", new HashMap<>() {
							{
								put("k2_3_1", "v2_3_1");
							}
						});
					}
				});
				put("k4", "var4");
			}
		};

		// 輸出 [var1, var2_1, {k2_3_1=v2_3_1}, var2_2, var4]
		var list4 = root.values()//
				.stream() //
				.flatMap(it -> {
					if (it instanceof Map) {
						return Arrays.stream(((Map<?, ?>) it).values().toArray());
					} else {
						return Arrays.stream(new Object[] { it });
					}
				}).collect(Collectors.toList());

		System.out.println(list4);

		// [var1, var2_1, v2_3_1, var2_2, var4]
		var list5 = flatMapFn.apply(root);
		System.out.println(list5);

	}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章