从Java流创建地图?

时间:2017-01-06 21:12:08

标签: java-8 java-stream

我正在尝试从map Java创建stream。我可以使用javascript轻松完成此操作,并尝试在Java中创建相同的内容。这是我的数据结构:

var slips = [
  {
    original: 'Y',
    lines: [
      {
        detailLines: {
          detailLineId: 111
        }
      },
      {
        detailLines: {
          detailLineId: 222
        }
      }
    ]
  },
  {
    original: 'N',
    lines: [
      {
        detailLines: {
          detailLineId: 333
        }
      },
      {
        detailLines: {
          detailLineId: 444
        }
      }
    ]
  }
]

以下是我在javascript

中的表现
var test = slips.reduce((acc, slip) => {
  slip.lines.map(line => line.detailLines.detailLineId)
            .map(arr => acc[arr] = slip.original);
  return acc;
}, {});

获取

的结果
{ 
  '111': 'Y', 
  '222': 'Y', 
  '333': 'N', 
  '444': 'N' 
}

如何使用Java 8 Stream api执行此操作?上面的slips实际上只是POJO。我将其转换为JSON对象,以便在js中进行计算。对象的真实结构是

class Slip {
  private Boolean original;
  private List<Line> lines;
}

class Line {
  private List<DetailLine> detailLines;
}

class DetailLine {
  private Long detailLine;
}

所以我从Java开始的是

Map<Long, Boolean> results = slips.stream().reduce(new Map<Long, Boolean>, ...)

2 个答案:

答案 0 :(得分:2)

对我来说,它看起来像一个线条对象包含一个细节线而不是一个列表。

string file "C:\\MyProject\\data.txt"; // let's say a valid path

ifstream filein(file.c_str());

if(filein.fail()) // the condition fails as long as the opening was successfull
    cout << "failed to open file!" << endl;

cout << "Insert Path" << endl;
cin >> file; // let's say the user enters a valid path again: "C:\\MyProject\\test.txt"

cout << file << endl;

filein.open(file.c_str(), ios::in); // fail to correct it:

filein.close();
filein.clear(); // very important

filein.open(file.c_str(), ios::in); // now it's ok!

for (string line; getline(filein, line);) {
    cout << line << endl;
}

假设每个详细信息行ID都是唯一的,您可以使用class Slip { private Boolean original; private List<Line> lines; } class Line { private DetailLine detailLine; } class DetailLine { private Long detailLineId; } 创建必要的映射ID - &gt;布尔,只需将它们收集到地图中即可。

flatMap

如果您确实拥有自己声明的结构,则应import java.util.AbstractMap.SimpleEntry; import static java.util.stream.Collectors.toMap; ... Map<Long, Boolean> results = slips.stream() .flatMap(s -> s.getLines().stream().map(l -> new SimpleEntry<>(l.getDetailLine().getDetailLineId(), s.getOriginal()))) .collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue)) 两次:

flatMap

答案 1 :(得分:0)

这是一个工作示例

import java.util.*;
import java.util.stream.Collectors;

public class Main {

    public static void main(String[] args) {

        List<DetailLine> detailedLines1 = new ArrayList<DetailLine>();
        detailedLines1.add(new DetailLine(111l));
        detailedLines1.add(new DetailLine(222l));

        List<DetailLine> detailedLines2 = new ArrayList<DetailLine>();
        detailedLines2.add(new DetailLine(333l));
        detailedLines2.add(new DetailLine(444l));


        Line line1 = new Line(detailedLines1);
        Line line2 = new Line(detailedLines2);


        List<Line> lines1 = new ArrayList<Line>();
        lines1.add(line1);

        List<Line> lines2 = new ArrayList<Line>();
        lines2.add(line2);

        List<Slip> slips = new ArrayList<Slip>();
        slips.add(new Slip(true, lines1));
        slips.add(new Slip(false, lines2));

        Map<Long, Boolean> myResult = new HashMap<>();


        slips.stream().map(
                slip ->
                        slip.getLines().stream().map(
                                line -> line.getDetailLines().stream().map(deadLine -> deadLine.getDetailLine()).collect(Collectors.toList())
                        ).flatMap(Collection::stream)
                                .map(l -> new AbstractMap.SimpleEntry<>(l, slip.getOriginal()))
        ).flatMap(l -> l).forEach(System.out::println);
    }

}

<强>输出

111=true
222=true
333=false
444=false