很久没有上博客园了,最近一段时间,因为工作的关系时间上比较闲,利用闲暇时间重新翻了一下丢弃很久的C++语言。C++从98、11、14、17目前已经也走到了20版本,发生了很多变化,也引入了很多新的语言特性和库,让开发也更加的便、高效。

但用惯了Java后,发现其中Java的容器流式操作特别简单,封装的很是优雅。而在C++中,针对容器的操作,与算法是完全分隔的,操作起来利用迭代器进行串接,这种方式其实本身实际上复用效率特别高效,但是对于开发者来说,又显得有些低效,考虑到这个问题,我自己对C++的容器与算法,简单做了一个封装。

话不多说,直接上代码,让大家看看效果!

示例代码

    vector<int> vec = {1, 3, 4, 6, 4, 2, 11, 9};
auto minmax = JavaStyleStream<vector, int>(vec)
.filter([](int i) { return i % 3 == 0; })
.transform([](int i){return i*2.5;})
.sort()
.for_each([](double i) { std::cout << i << " ";})
.minmax();
cout << minmax.first << ":" << minmax.second << endl;

最终结果

7.5 15 22.5 7.5:22.5

看到这里,是不是觉得容器操作起来要高效很多,不用再面对一成不变的迭代器了。

详细的Java Style容器流式封装类,见下面代码(未完整封装C++所有算法,工作还在进行中),觉得好用,麻烦点个赞,也欢迎大家提出宝贵意见

//
// Created by AILI on 2022/10/6.
// #ifndef CPPTEST_JAVASTYLESTREAM_H
#define CPPTEST_JAVASTYLESTREAM_H #include <algorithm>
#include "function_traits.h" //template <template<typename, typename> class Cont>
//struct Stream {}; template<template<typename T1, typename T2> class Cont, typename Tp, typename Alloc = std::allocator<Tp>>
class JavaStyleStream {
public:
typedef typename Cont<Tp, Alloc>::value_type value_type;
typedef typename Cont<Tp, Alloc>::pointer pointer;
typedef typename Cont<Tp, Alloc>::const_pointer const_pointer;
typedef typename Cont<Tp, Alloc>::reference reference;
typedef typename Cont<Tp, Alloc>::const_reference const_reference;
typedef typename Cont<Tp, Alloc>::iterator iterator;
typedef typename Cont<Tp, Alloc>::const_iterator const_iterator;
typedef typename Cont<Tp, Alloc>::const_reverse_iterator const_reverse_iterator;
typedef typename Cont<Tp, Alloc>::reverse_iterator reverse_iterator;
typedef typename Cont<Tp, Alloc>::size_type size_type;
typedef typename Cont<Tp, Alloc>::difference_type difference_type;
typedef typename Cont<Tp, Alloc>::allocator_type allocator_type; //聚合
value_type max() {
return *max_element();
} template<typename _Compare>
value_type max(_Compare compare) {
return *max_element();
} iterator max_element() {
return std::max_element(_container.begin(), _container.end());
} template<typename _Compare>
iterator max_element(_Compare compare) {
return std::max_element(_container.begin(), _container.end(), compare);
} value_type min() {
return *min_element();
} template<typename _Compare>
value_type min(_Compare compare) {
return *min_element(compare);
} iterator min_element() {
return std::min(_container.begin(), _container.end());
} template<typename _Compare>
iterator min_element(_Compare compare) {
return std::min(_container.begin(), _container.end(), compare);
} pair<value_type, value_type> minmax() {
pair<const_iterator, const_iterator> r = minmax_element();
return pair<value_type, value_type>(*(r.first), *(r.second));
} pair<const_iterator, const_iterator> minmax_element() {
return std::minmax_element(_container.begin(), _container.end());
} template<typename _Compare>
pair<const_iterator, const_iterator> minmax_element(_Compare compare) {
return std::minmax_element(_container.begin(), _container.end(), compare);
} difference_type count(const value_type& value) {
return std::count(_container.begin(), _container.end(), value);
} template<typename _Predicate>
difference_type count_if(_Predicate predicate) {
return std::count_if(_container.begin(), _container.end(), predicate);
} //查找
template<typename _Predicate>
bool all_of(_Predicate predicate) {
return std::all_of(_container.begin(), _container.end(), predicate);
} template<typename _Predicate>
bool any_of(_Predicate predicate) {
return std::any_of(_container.begin(), _container.end(), predicate);
} template<typename _Predicate>
bool none_of(_Predicate predicate) {
return std::none_of(_container.begin(), _container.end(), predicate);
} iterator adjacent_find() {
return std::adjacent_find(_container.begin(), _container.end());
} template<typename _BinaryPredicate>
iterator adjacent_find(_BinaryPredicate predicate) {
return std::adjacent_find(_container.begin(), _container.end(), predicate);
} iterator find(const value_type& value) {
return std::find(_container.begin(), _container.end(), value);
} template<typename _Predicate>
iterator find_if(_Predicate predicate) {
return std::find_if(_container.begin(), _container.end(), predicate);
} iterator find_first_of(iterator find_begin, iterator find_end) {
return std::find_first_of(_container.begin(), _container.end(), find_begin, find_end);
} template<typename _BinaryPredicate>
iterator find_first_of(iterator find_begin, iterator find_end, _BinaryPredicate predicate) {
return std::find_first_of(_container.begin(), _container.end(), find_begin, find_end, predicate);
} iterator find_end(iterator find_begin, iterator find_end) {
return std::find_end(_container.begin(), _container.end(), find_begin, find_end);
} template<typename _BinaryPredicate>
iterator find_end(iterator find_begin, iterator find_end, _BinaryPredicate predicate) {
return std::find_end(_container.begin(), _container.end(), find_begin, find_end, predicate);
} iterator binary_search(const value_type& value) {
return std::binary_search(_container.begin(), _container.end(), value);
} template<typename _Compare>
iterator binary_search(const value_type& value, _Compare compare) {
return std::binary_search(_container.begin(), _container.end(), value, compare);
} iterator search(const value_type& value) {
return std::search(_container.begin(), _container.end(), value);
} template<typename _BinaryPredicate>
iterator search(iterator find_begin, iterator find_end, _BinaryPredicate predicate) {
return std::search(_container.begin(), _container.end(), find_begin, find_end, predicate);
} iterator search_n(size_type n, const value_type& value) {
return std::search_n(_container.begin(), _container.end(), n, value);
} template<typename _BinaryPredicate>
iterator search_n(size_type n, const value_type& value, _BinaryPredicate predicate) {
return std::search_n(_container.begin(), _container.end(), n, value, predicate);
} iterator lower_bound(const value_type& value) {
return std::lower_bound(_container.begin(), _container.end(), value);
} template<typename _Compare>
iterator lower_bound(const value_type& value, _Compare compare) {
return std::lower_bound(_container.begin(), _container.end(), value, compare);
} iterator upper_bound(const value_type& value) {
return std::upper_bound(_container.begin(), _container.end(), value);
} template<typename _Compare>
iterator upper_bound(const value_type& value, _Compare compare) {
return std::upper_bound(_container.begin(), _container.end(), value, compare);
} //排序
bool is_sorted() {
return std::is_sorted(_container.begin(), _container.end());
} template<typename _Compare>
bool is_sorted(_Compare compare) {
return std::is_sorted(_container.begin(), _container.end(), compare);
} bool is_sorted_until() {
return std::is_sorted_until(_container.begin(), _container.end());
} template<typename _Compare>
bool is_sorted_until(_Compare compare) {
return std::is_sorted_until(_container.begin(), _container.end(), compare);
} JavaStyleStream& sort() {
std::sort(_container.begin(), _container.end());
return *this;
} template<typename _Compare>
JavaStyleStream& sort(_Compare compare) {
std::sort(_container.begin(), _container.end(), compare);
return *this;
} template<typename _Integer>
JavaStyleStream& partial_sort(_Integer integer) {
std::partial_sort(_container.begin(), _container.begin() + integer, _container.end());
return *this;
} template<typename _Integer, typename _Compare>
JavaStyleStream& partial_sort(_Integer integer, _Compare compare) {
std::partial_sort(_container.begin(), _container.begin() + integer, _container.end(), compare);
return *this;
} JavaStyleStream& stable_sort() {
std::stable_sort(_container.begin(), _container.end());
return *this;
} template<typename _Compare>
JavaStyleStream& stable_sort(_Compare compare) {
std::stable_sort(_container.begin(), _container.end(), compare);
return *this;
} template<typename _Integer>
JavaStyleStream& nth_element(_Integer integer) {
std::nth_element(_container.begin(), _container.begin() + integer, _container.end());
return *this;
} template<typename _Integer, typename _Compare>
JavaStyleStream& nth_element(_Integer integer, _Compare compare) {
std::nth_element(_container.begin(), _container.begin() + integer, _container.end(), compare);
return *this;
} JavaStyleStream& shuffle() {
std::shuffle(_container.begin(), _container.end());
return *this;
} template<typename _Generator>
JavaStyleStream& shuffle(_Generator generator) {
std::shuffle(_container.begin(), _container.end(), generator);
return *this;
} JavaStyleStream& random_shuffle() {
std::random_shuffle(_container.begin(), _container.end());
return *this;
} template<typename _Generator>
JavaStyleStream& random_shuffle(_Generator generator) {
std::random_shuffle(_container.begin(), _container.end(), generator);
return *this;
} //删除&替换
JavaStyleStream& remove_erase(const value_type& value) {
_container.erase(std::remove(_container.begin(), _container.end(), value), _container.end());
return *this;
} template<typename _Predicate>
JavaStyleStream& remove_erase(_Predicate predicate) {
_container.erase(std::remove_if(_container.begin(), _container.end(), predicate), _container.end());
return *this;
} JavaStyleStream& repalce(const value_type& old_value, const value_type& new_value) {
std::replace(_container.begin(), _container.end(), old_value, new_value);
return *this;
} template<typename _Predicate>
JavaStyleStream& replace_if(_Predicate predicate, const value_type& new_value) {
std::remove_if(_container.begin(), _container.end(), predicate, new_value);
return *this;
} //反转&旋转
JavaStyleStream& reverse() {
std::reverse(_container.begin(), _container.end());
return *this;
} template<typename _Integer>
JavaStyleStream& reverse(_Integer integer) {
std::rotate(_container.begin(), _container.begin() + integer, _container.end());
return *this;
} //归一化
JavaStyleStream& unique() {
std::unique(_container.begin(), _container.end());
return *this;
} template<typename _BinaryPredicate>
JavaStyleStream& unique(_BinaryPredicate predicate) {
std::unique(_container.begin(), _container.end(), predicate);
return *this;
} //分组(是否需要返回分组迭代器?)
template<typename _Predicate>
JavaStyleStream& partition(_Predicate predicate) {
std::partition(_container.begin(), _container.end(), predicate);
return *this;
} template<typename _Predicate>
JavaStyleStream& stable_partition(_Predicate predicate) {
std::stable_partition(_container.begin(), _container.end(), predicate);
return *this;
} //C++11提供
template<typename _Predicate>
JavaStyleStream& partition_point(_Predicate predicate) {
std::partition_point(_container.begin(), _container.end(), predicate);
return *this;
} //过滤&复制&合并&转换
template<typename _Predicate>
JavaStyleStream filter(_Predicate predicate) {
Cont<Tp, Alloc> newCont;
for(iterator iter = _container.begin(); iter != _container.end(); ++iter) {
if (predicate(*iter)) {
newCont.push_back(*iter);
}
} JavaStyleStream<Cont, Tp> newSteram(newCont);
return std::move(newSteram);
} template<typename _UnaryFunction>
JavaStyleStream<Cont, typename function_traits<_UnaryFunction>::return_type> transform(_UnaryFunction function) {
Cont<typename function_traits<_UnaryFunction>::return_type, std::allocator<typename function_traits<_UnaryFunction>::return_type>> newCont;
std::transform(_container.begin(), _container.end(), std::back_inserter(newCont), function); JavaStyleStream<Cont, typename function_traits<_UnaryFunction>::return_type, std::allocator<typename function_traits<_UnaryFunction>::return_type>> newStream(newCont);
return std::move(newStream);
} //复制
JavaStyleStream copy() {
Cont<Tp, Alloc> newCont;
std::copy(_container.begin(), _container.end(), std::back_inserter(newCont)); JavaStyleStream<Cont, Tp> newStream(newCont);
return newStream;
} template<typename _Predicate>
JavaStyleStream copy_if(_Predicate predicate) {
Cont<Tp, Alloc> newCont;
std::copy_if(_container.begin(), _container.end(), std::back_inserter(newCont), predicate); JavaStyleStream<Cont, Tp> newStream(newCont);
return newStream;
} template<typename _Integer>
JavaStyleStream copy_n(_Integer integer) {
Cont<Tp, Alloc> newCont;
std::copy_n(_container.begin(), integer, std::back_inserter(newCont)); JavaStyleStream<Cont, Tp> newStream(newCont);
return newStream;
} JavaStyleStream copy_backward() {
Cont<Tp, Alloc> newCont;
std::copy_backward(_container.begin(), _container.end(), std::back_inserter(newCont)); JavaStyleStream<Cont, Tp> newStream(newCont);
return newStream;
} //遍历
template<typename _Function>
JavaStyleStream& for_each(_Function function) {
std::for_each(_container.begin(), _container.end(), function); return *this;
} //reduce //集合 public:
JavaStyleStream(Cont<Tp, Alloc>& container)
: _container(container)
{}; JavaStyleStream(JavaStyleStream& stream)
: _container(stream._container)
{}; JavaStyleStream(JavaStyleStream&& stream)
: _container(stream._container)
{}; private:
Cont<Tp, Alloc> _container;
}; #endif //CPPTEST_JAVASTYLESTREAM_H

Java Style的C++容器流式处理类的更多相关文章

  1. java基础之-I/O流和File类解析

    在日常的java开发中少不了文件的读取和 写入,这就涉及到文件的I/O操作,今天就来总结下文件的IO操作,顺便文件的IO操作也需要File了的帮助,所以一起总结了. 以下图片为我根据其他博客所总结的内 ...

  2. java基础9(IO流)-File类

    File类 File:文件和目录路径名的抽象表示形式.即java中把文件或者目录都封装成File对象 代码练习1 import java.io.File; public class FileDemo1 ...

  3. 自定义ViewGroup 流式布局

    使用 public class MainActivity extends Activity {     @Override     protected void onCreate(Bundle sav ...

  4. 20190827 On Java8 第十四章 流式编程

    第十四章 流式编程 流的一个核心好处是,它使得程序更加短小并且更易理解.当 Lambda 表达式和方法引用(method references)和流一起使用的时候会让人感觉自成一体.流使得 Java ...

  5. 转:Java图形化界面设计——布局管理器之FlowLayout(流式布局)其他请参考转载出处网址

    http://blog.csdn.net/liujun13579/article/details/7771191 前文讲解了JFrame.JPanel,其中已经涉及到了空布局的使用.Java虽然可以以 ...

  6. Java图形化界面设计——布局管理器之FlowLayout(流式布局)

    一.布局管理器所属类包 所属类包 布局管理器名称 说明 Java.awt FlowLayout(流式布局) 组件按照加入的先后顺序按照设置的对齐方式从左向右排列,一行排满到下一行开始继续排列 Bord ...

  7. Java开发笔记(七十二)Java8新增的流式处理

    通过前面几篇文章的学习,大家应能掌握几种容器类型的常见用法,对于简单的增删改和遍历操作,各容器实例都提供了相应的处理方法,对于实际开发中频繁使用的清单List,还能利用Arrays工具的asList方 ...

  8. 03 Java图形化界面设计——布局管理器之FlowLayout(流式布局)

    前文讲解了JFrame.JPanel,其中已经涉及到了空布局的使用.Java 虽然可以以像素为单位对组件进行精确的定位,但是其在不同的系统中将会有一定的显示差异,使得显示效果不尽相同,为此java提供 ...

  9. Java流式思想和方法引用

    目录 Java流式思想和方法引用 1. Stream流 1.1 概述 传统集合的多步遍历代码 Stream的更优写法 1.2 流式思想的概述 1.3 获取流 1.4 常用方法 ①逐一处理:forEac ...

随机推荐

  1. get 和 post 的区别

    1. get 提交的信息显示在地址栏中 post 提交的信息不显示在地址栏中 2. get 对于敏感数据信息不安全,因为信息显示在地址栏中 post 对于敏感数据安全 3. get 不支持大数据量请求 ...

  2. 丽泽普及2022交流赛day19 半社论

    目录 No Problem Str Not TSP 题面 题解 代码 Game 题面 题解 代码 No Problem 暴力 Str 存在循环节,大力找出来即可,长度显然不超过 \(10^3\) . ...

  3. mysql Insert强化

    INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [(col_name,...)] VALUES ({e ...

  4. SQL 字符串去除空格函数汇总

    SQL 中使用ltrim()去除左边空格 ,rtrim()去除右边空格 ,没有同时去除左右空格的函数,要去除所有空格可以用replace(字符串,' ',''),将字符串里的空格替换为空 . 例:去除 ...

  5. 6.8 NOI 模拟

    \(T1\ edge\) 考虑\(O(q\times n\times \log n)\)的暴力 暴力二分,直接树上差分 #define Eternal_Battle ZXK #include<b ...

  6. SQL 注入复习总结

    一.介绍 1.什么是SQL注入? sql 注入是一种将 sql 代码添加到输入参数中,传递到 sql 服务器解析并执行的一种攻击手法. 2.SQL注入的原理 SQL 是操作数据库数据的结构化查询语言, ...

  7. 技术分享 | 在GreatDB分布式部署模式中使用Chaos Mesh做混沌测试

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 1. 需求背景与万里安全数据库软件GreatDB分布式部署模式介绍 1.1 需求背景 混沌测试是检测分布式系统不确定性.建 ...

  8. MySQL查询性能优化七种武器之索引潜水

    有读者可能会一脸懵逼? 啥是索引潜水? 你给起的名字的吗?有没有索引蛙泳? 这个名字还真不是我起的,今天要讲的知识点就叫索引潜水(Index dive). 先要从一件怪事说起: 我先造点数据复现一下问 ...

  9. 前端监控系列1| 字节的前端监控SDK是怎样设计的

    作者:彭莉,火山引擎 APM 研发工程师,2020年加入字节,负责前端监控 SDK 的开发维护.平台数据消费的探索和落地. 摘要 字节内部应用环境多样( Web 应用.小程序.Electron 应用. ...

  10. Python爬虫之xpath语法及案例使用

    Python爬虫之xpath语法及案例使用 ---- 钢铁侠的知识库 2022.08.15 我们在写Python爬虫时,经常需要对网页提取信息,如果用传统正则表达去写会增加很多工作量,此时需要一种对数 ...