Java 8分区列表

时间:2015-06-23 06:52:23

标签: java java-8 partitioning

是否可以将纯Jdk8中的List分区为相等的块(子列表)。

我知道可以使用Guava Lists类,但我们可以使用纯Jdk吗?我不想在我的项目中添加新的jar,仅用于一个用例。

SOLUTONS

迄今为止最好的解决方案由tagir-valeev提供:

我也找到了three other possibilities,但它们只适用于少数情况:

1.Collectors.partitioningBy()将列表拆分为2个子列表 - 如下所示:

intList.stream().collect(Collectors.partitioningBy(s -> s > 6));
    List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());

2.Collectors.groupingBy()将我们的列表拆分为多个分区:

 Map<Integer, List<Integer>> groups = 
      intList.stream().collect(Collectors.groupingBy(s -> (s - 1) / 3));
    List<List<Integer>> subSets = new ArrayList<List<Integer>>(groups.values());

3.Split by separator:

List<Integer> intList = Lists.newArrayList(1, 2, 3, 0, 4, 5, 6, 0, 7, 8);

    int[] indexes = 
      Stream.of(IntStream.of(-1), IntStream.range(0, intList.size())
      .filter(i -> intList.get(i) == 0), IntStream.of(intList.size()))
      .flatMapToInt(s -> s).toArray();
    List<List<Integer>> subSets = 
      IntStream.range(0, indexes.length - 1)
               .mapToObj(i -> intList.subList(indexes[i] + 1, indexes[i + 1]))
               .collect(Collectors.toList());

4.使用Streams + counter source

final List<Integer> numbers = Arrays.asList(1,2,3,4,5,6,7);
final int chunkSize = 3;
final AtomicInteger counter = new AtomicInteger();

final Collection<List<Integer>> result = numbers.stream()
    .collect(Collectors.groupingBy(it -> counter.getAndIncrement() / chunkSize))
    .values();

5 个答案:

答案 0 :(得分:20)

使用subList()方法可以轻松完成:

List<String> collection = new ArrayList<>(21);
// fill collection
int chunkSize = 10;
List<List<String>> lists = new ArrayList<>();
for (int i = 0; i < collection.size(); i += chunkSize) {
    int end = Math.min(collection.size(), i + chunkSize);
    lists.add(collection.subList(i, end));
}

答案 1 :(得分:2)

尝试使用此代码,它使用Java 8:

let mut m = 10;

let n = {
    let m2 = m;
    let mut a = &m2;
    let b = &a;
    &**b
};

println!("{:?}", n);

答案 2 :(得分:0)

我已经尝试使用定制的收集器来解决自己的问题。我希望有人会发现它有用或帮助我改进它。

//Image handler
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
curl_setopt($ch, CURLOPT_URL, $jsonresponse['url']);
$data = curl_exec($ch);
curl_close($ch);

$dataDecoded = base64_decode($data); //Last try with base64 decoder
$fb_image = 'fb_picture.jpg';
file_put_contents($fb_image, $dataDecoded); 

答案 3 :(得分:0)

private final String dataSheet = "103343262,6478342944, 103426540,84528784843, 103278808,263716791426, 103426733,27736529279, 
103426000,27718159078, 103218982,19855201547, 103427376,27717278645, 
103243034,81667273413";

    final int chunk = 2;
    AtomicInteger counter = new AtomicInteger();
    Collection<List<String>> chuncks= Arrays.stream(dataSheet.split(","))
            .map(String::trim)
            .collect(Collectors.groupingBy(i->counter.getAndIncrement()/chunk))
            .values();
  

结果:

pairs =
 "103218982" -> "19855201547"
 "103278808" -> "263716791426"
 "103243034" -> "81667273413"
 "103426733" -> "27736529279"
 "103426540" -> "84528784843"
 "103427376" -> "27717278645"
 "103426000" -> "27718159078"
 "103343262" -> "6478342944"
  

我们需要将每2个元素分组为键,值对,因此将列表分成2个块(counter.getAndIncrement()/ 2),每2次命中将产生相同的数字,例如:

IntStream.range(0,6).forEach((i)->System.out.println(counter.getAndIncrement()/2));
prints:
0
0
1
1
2
2
  

您可以将块大小调整为分区列表大小。

答案 4 :(得分:0)

Guava Lists类具有一个完全做到这一点的partition()方法。参见https://guava.dev/releases/21.0/api/docs/com/google/common/collect/Lists.html#partition-java.util.List-int-