这篇文章主要围绕在for循环中重新创建ArrayList的最快方法和for循环重新循环展开,旨在为您提供一份详细的参考资料。我们将全面介绍在for循环中重新创建ArrayList的最快方法的优缺点,解
这篇文章主要围绕在for循环中重新创建ArrayList的最快方法和for循环重新循环展开,旨在为您提供一份详细的参考资料。我们将全面介绍在for循环中重新创建ArrayList的最快方法的优缺点,解答for循环重新循环的相关问题,同时也会为您带来Array.fill和for循环创建Array有什么区别、ArrayList list = new ArrayList()在这个泛型为Integer的ArrayList中存放一个String类型的对象、ArrayList在for循环中使用remove方法移除元素方法介绍、c – 在for循环中重新排序测试条件:编译器错误?的实用方法。
本文目录一览:- 在for循环中重新创建ArrayList的最快方法(for循环重新循环)
- Array.fill和for循环创建Array有什么区别
- ArrayList list = new ArrayList()在这个泛型为Integer的ArrayList中存放一个String类型的对象
- ArrayList在for循环中使用remove方法移除元素方法介绍
- c – 在for循环中重新排序测试条件:编译器错误?
在for循环中重新创建ArrayList的最快方法(for循环重新循环)
在Java中,对巨大的矩阵X使用以下函数来打印其列不相同的元素:
// create the list of distinct valuesList<Integer> values = new ArrayList<Integer>();// X is n * m int[][] matrixfor (int j = 0, x; j < m; j++) { values.clear(); for (int i = 0; i < n; i++) { x = X[i][j]; if (values.contains(x)) continue; System.out.println(x); values.add(x); }}
首先,我按列(索引j)进行迭代,并按行(索引i)进行内部迭代。
对于不同的矩阵,此函数将被调用数百万次,因此应优化代码以满足性能要求。我想知道关于values数组。使用values = newArrayList<Integer>();
还是values = null
代替它会更快values.clear()
?
答案1
小编典典效率更高的方法是使用Set而不是列表,例如HashSet实现。contains方法将在O(1)中运行,而不是在带有列表的O(n)中运行。您可以只调用add方法来保存一个调用。
至于您的特定问题,我将在每个循环处创建一个新的Set-对象创建并没有那么昂贵,可能比清除该set少(如底部的基准所确认-请参见EDIT 2中最有效的版本):
for (int j = 0, x; j < m; j++) { Set<Integer> values = new HashSet<Integer>(); for (int i = 0; i < n; i++) { x = X[i][j]; if (!values.add(x)) continue; //value.add returns true if the element was NOT in the set before System.out.println(x); }}
但是,知道哪个更快(新对象还是清除对象)的唯一方法是分析代码的那部分并检查两个版本的性能。
编辑
我运行了一个快速基准测试,清晰的版本似乎比在每个循环上创建一个集合要快一些(大约20%)。您仍然应该检查数据集/用例中哪一个更好。我的数据集的代码更快:
Set<Integer> values = new HashSet<Integer>();for (int j = 0, x; j < m; j++) { for (int i = 0; i < n; i++) { x = X[i][j]; if (!values.add(x)) continue; //value.add returns true if the element was NOT in the set before System.out.println(x); } values.clear();}
编辑2
通过在每个循环中创建一组正确大小的新代码,可以获得实际上甚至更快的代码版本:
for (int j = 0, x; j < m; j++) { Set<Integer> values = new HashSet<Integer>(n, 1); //right size from the beginning for (int i = 0; i < n; i++) { x = X[i][j]; if (!values.add(x)) continue; //value.add returns true if the element was NOT in the set before System.out.println(x); }}
结果汇总
JVM预热+ JIT之后:
Set<Integer> values = new HashSet<Integer>(n, 1); =====> 280 msvalues.clear(); =====> 380 msSet<Integer> values = new HashSet<Integer>(); =====> 450 ms
Array.fill和for循环创建Array有什么区别
我正在使用React.js创建一个地牢爬虫游戏,并且正在使用Array.fill(0)来初始化棋盘。但是当我在2d数组内设置元素时,它将整个Array(列)设置为,'player'
而不是单个元素。我有另一个createBoard()
功能,注释掉,可以正常工作。那么,为什么会发生这种情况?如何正确使用Array.fill?
这是我的董事会组件:
import React,{Component} from 'react';
import Cell from './Cell';
class Board extends Component {
constructor(props) {
super(props);
const dim = 10;
let board = this.createBoard(dim,dim);
this.state = {
board: board,};
}
createBoard = (row,col) => {
return Array(row).fill(Array(col).fill(0));
}
// createBoard = (rows,cols) => {
// let board = [];
// for (let i = 0; i < rows; i++) {
// let row = [];
// for (let j = 0; j < cols; j++) {
// row.push(0);
// }
// board.push(row);
// }
// console.log(board);
// return board;
// }
movePlayer = () => {
}
componentDidMount() {
this.setPiece(this.props.player);
}
setPiece = (loc) => {
let brd = this.state.board;
const row = loc[0];
const col = loc[1];
console.log('row: '+row+' col: '+col+' ==='+brd[row][col]);
brd[row][col] = 'player';
console.log('setPiece: ',brd);
this.setState({board: brd});
}
renderCell = (cell) => {
switch(cell) {
case 0:
return 'floor';
case 1:
return 'wall';
case 'player':
return 'player';
default:
return 'floor';
}
}
render() {
return (
<div className='board'>
{this.state.board.map((row,i) => {
return row.map((cell,j) => {
return (
<Cell
key={[i,j]}
loc={[i,j]}
type={this.renderCell(cell)}
/>
);
})
})}
</div>
);
}
}
export default Board;
ArrayList list = new ArrayList()在这个泛型为Integer的ArrayList中存放一个String类型的对象
java面试要点---ArrayList list = new ArrayList(); 在这个泛型为Integer的ArrayList中存放一个String类型的对象。
1.刚刚看到的时候,也是很纳闷后来仔细看了下,java的反射机制;
2.这个可以通过java的反射机制来实现;
3.下面是一个例子:
package com.credream.refelect;
------------------------------------------------------------------------------------------------------------------
运行结果:
35
ArrayList在for循环中使用remove方法移除元素方法介绍
有时候我们需要在一个ArrayList的for循环中动态删除元素的需求,废话不多说看代码
List<Integer> list = new ArrayList<Integer>(); list.add(0); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); list.add(6); list.add(7); //正常循环 for (int i = 0; i < list.size(); i++) { System.out.println("i的值:" + i + " 对应的数字:" + list.get(i)); } System.out.println("没有remove前list的项:"+list.size()); //边循环边删除 for (int i = 0; i < list.size(); i++) { System.out.println("i的值:" + i + " 对应的数字:" + list.get(i)); if(list.get(i) == 3) list.remove(list.get(i));//删除list的第四项 } System.out.println("remove后list的项:"+list.size()); System.out.println("==========remove后的list=========="); for (int i = 0; i < list.size(); i++) { System.out.println("i的值:" + i + " 对应的数字:" + list.get(i)); }
执行代码,结果如下:
i的值:0 对应的数字:0 i的值:1 对应的数字:1 i的值:2 对应的数字:2 i的值:3 对应的数字:3 i的值:4 对应的数字:4 i的值:5 对应的数字:5 i的值:6 对应的数字:6 i的值:7 对应的数字:7 没有remove前list的项:8 i的值:0 对应的数字:0 i的值:1 对应的数字:1 i的值:2 对应的数字:2 i的值:3 对应的数字:3 i的值:4 对应的数字:5 i的值:5 对应的数字:6 i的值:6 对应的数字:7 remove后list的项:7 ==========remove后的list========== i的值:0 对应的数字:0 i的值:1 对应的数字:1 i的值:2 对应的数字:2 i的值:3 对应的数字:4 i的值:4 对应的数字:5 i的值:5 对应的数字:6 i的值:6 对应的数字:7
可以看到没有删除前,我们的list的项和循环对应的数字都是正确的,但是下面的循环在删除第4个元素后,第4,5,6个项对应的数字本应该是4,6,但是这里却变成了5,7.
原因是,我们删除第4项后,list的长度就变成7,而且,list会把第4项后面的值往前移一位,也就是说,i=3时,list.get(i)=4,i=4时,list.get(i)=5,i=5时,list.get(i)=6,i=6时,list.get(i)=7.. 我们再说的形象一点,就是本来有8层糕点,依次是0-7,竖起来,大的在上,小的在下,我们从下往上数,数到第5个的时候,吃掉这一层糕点,这时,上面三层分别往下移了一层
所以,值为4的项我们根本没有循环到
那有什么方法可以实现remove呢,有个笨方法,是新建一个tempList,把要删除的项全部add进去,最后用list.removeAll(tempList)实现 . 但是这里我们有更好的方法,就是倒序删除
还是上面的例子,我们看代码:
List<Integer> list = new ArrayList<Integer>(); list.add(0); list.add(1); list.add(2); list.add(3); list.add(4); list.add(5); list.add(6); list.add(7); //正常循环 for (int i = 0; i < list.size(); i++) { System.out.println("i的值:" + i + " 对应的数字:" + list.get(i)); } System.out.println("没有remove前list的项:"+list.size()); //边循环边删除 for (int i = list.size() -1 ; i >= 0; i--) { System.out.println("i的值 " + i + " 对应的数字 " + list.get(i)); if(list.get(i) == 3) list.remove(list.get(i)); } System.out.println("remove后list的项:"+list.size()); System.out.println("==========remove后的list=========="); for (int i = 0; i < list.size(); i++) { System.out.println("i的值 " + i + " 对应的数字 " + list.get(i)); }
执行代码,结果如下:
i的值:0 对应的数字:0 i的值:1 对应的数字:1 i的值:2 对应的数字:2 i的值:3 对应的数字:3 i的值:4 对应的数字:4 i的值:5 对应的数字:5 i的值:6 对应的数字:6 i的值:7 对应的数字:7 没有remove前list的项:8 i的值 7 对应的数字 7 i的值 6 对应的数字 6 i的值 5 对应的数字 5 i的值 4 对应的数字 4 i的值 3 对应的数字 3 i的值 2 对应的数字 2 i的值 1 对应的数字 1 i的值 0 对应的数字 0 remove后list的项:7 ==========remove后的list========== i的值 0 对应的数字 0 i的值 1 对应的数字 1 i的值 2 对应的数字 2 i的值 3 对应的数字 4 i的值 4 对应的数字 5 i的值 5 对应的数字 6 i的值 6 对应的数字 7
我们可以看到变循环变删除,并不影响后面的元素,remove后的list也和第一次的结果是一样的 . 这是因为我们删除list元素,list的长度是会变小,但是变化的只是比当前被删除元素的项大的项,而我们这里使用倒序循环,大的项,我们已经执行过了,所以不会影响.. 再用上面的比喻来说明,这次我们是从上往下数,数到第4个的时候,上面三层分别往下移了一层,但是这不影响我们之前数过的蛋糕,而且对下面的蛋糕也不影响,这就是原理
总结
以上就是本文关于ArrayList在for循环中使用remove方法移除元素方法介绍的全部内容,希望对大家有所帮助。感兴趣的朋友可以参阅:Java实现跳跃表(skiplist)的简单实例 Java多线程ForkJoinPool实例详解 等。感谢朋友们对编程小技巧网站的支持。有什么问题或者想要了解的可以随时给我们留言,小编会及时回复大家的。
c – 在for循环中重新排序测试条件:编译器错误?
std::vector<Node> nodes = ... const unsigned short sentinel = -1; unsigned short index = 0; for (Node* node = &nodes[index]; // root node index != sentinel; node = &nodes[index]) { if (foo(*node)) { index = node->left; } else { index = node->right; } }
换句话说,没什么特别的.但是,MSVC 2012失败,尝试访问超出范围的节点[sentinel].事实证明,它首先计算& nodes [index],然后测试索引. (调试模式,无优化).
对我来说,这看起来像代码生成错误,但我至少在十年内没有看到过这样的错误.这是简单的未经优化的代码.当然,即使重新排列,在测试索引之前实际上并未使用节点,并且在x86上具有这样的越界指针并不是非常不安全,但是MSVC的向量<>合法地断言该非法指数.
干净的构造并再次检查组件;它是可重复的.树也不是空的,总是有一个根节点.
我忽略了什么,或者这真的是一个严重的编译器错误?
解决方法
Node* node = &nodes[index]; // root node while(index != sentinel) { { if (foo(*node)) { index = node->left; } else { index = node->right; } } node = &nodes[index]; }
最后一行可能是对节点[-1]的访问.
我会把你的循环改写成
unsigned short index = 0; do { Node* node = &nodes[index]; if (foo(*node)) { index = node->left; } else { index = node->right; } } while(index != sentinel);
今天关于在for循环中重新创建ArrayList的最快方法和for循环重新循环的介绍到此结束,谢谢您的阅读,有关Array.fill和for循环创建Array有什么区别、ArrayList list = new ArrayList()在这个泛型为Integer的ArrayList中存放一个String类型的对象、ArrayList在for循环中使用remove方法移除元素方法介绍、c – 在for循环中重新排序测试条件:编译器错误?等更多相关知识的信息可以在本站进行查询。
本文标签: