Java Style的C++容器流式处理类
很久没有上博客园了,最近一段时间,因为工作的关系时间上比较闲,利用闲暇时间重新翻了一下丢弃很久的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++容器流式处理类的更多相关文章
- java基础之-I/O流和File类解析
在日常的java开发中少不了文件的读取和 写入,这就涉及到文件的I/O操作,今天就来总结下文件的IO操作,顺便文件的IO操作也需要File了的帮助,所以一起总结了. 以下图片为我根据其他博客所总结的内 ...
- java基础9(IO流)-File类
File类 File:文件和目录路径名的抽象表示形式.即java中把文件或者目录都封装成File对象 代码练习1 import java.io.File; public class FileDemo1 ...
- 自定义ViewGroup 流式布局
使用 public class MainActivity extends Activity { @Override protected void onCreate(Bundle sav ...
- 20190827 On Java8 第十四章 流式编程
第十四章 流式编程 流的一个核心好处是,它使得程序更加短小并且更易理解.当 Lambda 表达式和方法引用(method references)和流一起使用的时候会让人感觉自成一体.流使得 Java ...
- 转:Java图形化界面设计——布局管理器之FlowLayout(流式布局)其他请参考转载出处网址
http://blog.csdn.net/liujun13579/article/details/7771191 前文讲解了JFrame.JPanel,其中已经涉及到了空布局的使用.Java虽然可以以 ...
- Java图形化界面设计——布局管理器之FlowLayout(流式布局)
一.布局管理器所属类包 所属类包 布局管理器名称 说明 Java.awt FlowLayout(流式布局) 组件按照加入的先后顺序按照设置的对齐方式从左向右排列,一行排满到下一行开始继续排列 Bord ...
- Java开发笔记(七十二)Java8新增的流式处理
通过前面几篇文章的学习,大家应能掌握几种容器类型的常见用法,对于简单的增删改和遍历操作,各容器实例都提供了相应的处理方法,对于实际开发中频繁使用的清单List,还能利用Arrays工具的asList方 ...
- 03 Java图形化界面设计——布局管理器之FlowLayout(流式布局)
前文讲解了JFrame.JPanel,其中已经涉及到了空布局的使用.Java 虽然可以以像素为单位对组件进行精确的定位,但是其在不同的系统中将会有一定的显示差异,使得显示效果不尽相同,为此java提供 ...
- Java流式思想和方法引用
目录 Java流式思想和方法引用 1. Stream流 1.1 概述 传统集合的多步遍历代码 Stream的更优写法 1.2 流式思想的概述 1.3 获取流 1.4 常用方法 ①逐一处理:forEac ...
随机推荐
- get 和 post 的区别
1. get 提交的信息显示在地址栏中 post 提交的信息不显示在地址栏中 2. get 对于敏感数据信息不安全,因为信息显示在地址栏中 post 对于敏感数据安全 3. get 不支持大数据量请求 ...
- 丽泽普及2022交流赛day19 半社论
目录 No Problem Str Not TSP 题面 题解 代码 Game 题面 题解 代码 No Problem 暴力 Str 存在循环节,大力找出来即可,长度显然不超过 \(10^3\) . ...
- mysql Insert强化
INSERT [LOW_PRIORITY | DELAYED | HIGH_PRIORITY] [IGNORE] [INTO] tbl_name [(col_name,...)] VALUES ({e ...
- SQL 字符串去除空格函数汇总
SQL 中使用ltrim()去除左边空格 ,rtrim()去除右边空格 ,没有同时去除左右空格的函数,要去除所有空格可以用replace(字符串,' ',''),将字符串里的空格替换为空 . 例:去除 ...
- 6.8 NOI 模拟
\(T1\ edge\) 考虑\(O(q\times n\times \log n)\)的暴力 暴力二分,直接树上差分 #define Eternal_Battle ZXK #include<b ...
- SQL 注入复习总结
一.介绍 1.什么是SQL注入? sql 注入是一种将 sql 代码添加到输入参数中,传递到 sql 服务器解析并执行的一种攻击手法. 2.SQL注入的原理 SQL 是操作数据库数据的结构化查询语言, ...
- 技术分享 | 在GreatDB分布式部署模式中使用Chaos Mesh做混沌测试
GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 1. 需求背景与万里安全数据库软件GreatDB分布式部署模式介绍 1.1 需求背景 混沌测试是检测分布式系统不确定性.建 ...
- MySQL查询性能优化七种武器之索引潜水
有读者可能会一脸懵逼? 啥是索引潜水? 你给起的名字的吗?有没有索引蛙泳? 这个名字还真不是我起的,今天要讲的知识点就叫索引潜水(Index dive). 先要从一件怪事说起: 我先造点数据复现一下问 ...
- 前端监控系列1| 字节的前端监控SDK是怎样设计的
作者:彭莉,火山引擎 APM 研发工程师,2020年加入字节,负责前端监控 SDK 的开发维护.平台数据消费的探索和落地. 摘要 字节内部应用环境多样( Web 应用.小程序.Electron 应用. ...
- Python爬虫之xpath语法及案例使用
Python爬虫之xpath语法及案例使用 ---- 钢铁侠的知识库 2022.08.15 我们在写Python爬虫时,经常需要对网页提取信息,如果用传统正则表达去写会增加很多工作量,此时需要一种对数 ...