
Leprechaun Software Developer
   
Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin
Репутация: 210 Всего: 538
|
В свое время мне нужен был кольцевой буфер, в принципе это то что сделал Sardar только чуточку более развитый и реализующий интерфейс Collection. | Код | public class RingBuffer implements Collection { private Object[] buffer; private int start , end;
public RingBuffer() { this(50); }
public RingBuffer(int capacity) { buffer = new Object[capacity + 1]; start = end = 0; }
public synchronized boolean isEmpty() { return start == end; }
public synchronized void clear() { for(int i = 0; i < buffer.length; i++) buffer[i] = null; start = end = 0; }
public synchronized int size() { if(start <= end) return end - start; else return (buffer.length - start) + end; }
public synchronized boolean contains(Object o) { if(start <= end) { for(int i = start; i < end; i++) { if(equals(o , buffer[i])) return true; } } else { for(int i = start; i < buffer.length; i++) { if(equals(o , buffer[i])) return true; } for(int i = 0; i < end; i++) { if(equals(o , buffer[i])) return true; } } return false; }
public synchronized boolean containsAll(Collection c) { for(Iterator i = c.iterator(); i.hasNext(); ) { Object item = i.next(); if(!contains(item)) return false; } return true; }
public boolean add(Object o) { push(o); return true; }
public synchronized boolean addAll(Collection c) { for(Iterator i = c.iterator(); i.hasNext(); ) { Object item = i.next(); add(item); } return c.size() > 0; }
public Iterator iterator() { return new RingIterator(); }
public synchronized Object[] toArray() { Object[] result; if(start <= end) { result = new Object[end - start]; System.arraycopy(buffer , start , result , 0 , result.length); } else { result = new Object[ (buffer.length - start) + end]; System.arraycopy(buffer , start , result , 0 , (buffer.length - start)); System.arraycopy(buffer , 0 , result , (buffer.length - start) , end); } return result; }
public synchronized Object[] toArray(Object[] a) { Object[] result; if(start <= end) { result = (Object[]) Array.newInstance(a.getClass().getComponentType() , end - start); System.arraycopy(buffer , start , result , 0 , result.length); } else { result = (Object[]) Array.newInstance(a.getClass().getComponentType() , (buffer.length - start) + end); System.arraycopy(buffer , start , result , 0 , (buffer.length - start)); System.arraycopy(buffer , 0 , result , (buffer.length - start) , end); } return result; }
public boolean remove(Object o) throws UnsupportedOperationException { throw new UnsupportedOperationException("RingBuffer does not support remove operation"); }
public boolean removeAll(Collection c) throws UnsupportedOperationException { throw new UnsupportedOperationException("RingBuffer does not support remove operation"); }
public boolean retainAll(Collection c) throws UnsupportedOperationException { throw new UnsupportedOperationException("RingBuffer does not support retain all operation"); }
public synchronized boolean equals(Object o) { if(! (o instanceof RingBuffer)) return false;
Iterator it1 = iterator(); Iterator it2 = ( (RingBuffer) o).iterator(); while(it1.hasNext() && it2.hasNext()) { Object o1 = it1.next(); Object o2 = it2.next(); if(!equals(o1 , o2)) return false; } return! (it1.hasNext() ^ it2.hasNext()); }
private static final boolean equals(Object o1 , Object o2) { return o1 == null ? o2 == null : o1.equals(o2); }
public synchronized void push(Object o) { buffer[end] = o; end = (end + 1) % buffer.length; if(end == start) { start = (start + 1) % buffer.length;; buffer[end] = null; } }
public synchronized Object pop() { if(start == end) throw new EmptyRingBufferException("RingBuffer is empty");
Object result = buffer[start]; buffer[start] = null; start = (start + 1) % buffer.length;; return result; }
public synchronized Object getLast() { if(start == end) throw new EmptyRingBufferException("RingBuffer is empty"); int last = (end == 0) ? buffer.length - 1 : end - 1; return buffer[last]; }
public synchronized Object getFirst() { if(start == end) throw new EmptyRingBufferException("RingBuffer is empty"); return buffer[start]; }
public synchronized int getCapacity() { return buffer.length - 1; }
public synchronized void setCapacity(int capacity) { if(capacity < 0) throw new IllegalArgumentException("Capacity must be positive"); if(capacity + 1 == buffer.length) return;
Object[] newBuffer = new Object[capacity + 1];
if(start <= end) { int nCopy = Math.min(end - start , capacity); int copyFrom = (end - start < capacity) ? start : end - capacity; System.arraycopy(buffer , copyFrom , newBuffer , 0 , nCopy); end = nCopy; } else { int nCopyEnd = Math.min(end , capacity); int nCopyStart = Math.min(buffer.length - start , capacity - nCopyEnd); System.arraycopy(buffer , buffer.length - nCopyStart , newBuffer , 0 , nCopyStart); System.arraycopy(buffer , end - nCopyEnd , newBuffer , nCopyStart , nCopyEnd); end = nCopyStart + nCopyEnd; } start = 0; buffer = newBuffer; }
public String toString() { return getClass().getName() + "[capacity = " + (buffer.length - 1) + ", size = " + ( (start <= end) ? end - start : buffer.length - start + end) + "]"; }
/*/ public String bufferToString() { StringBuffer str = new StringBuffer(toString()); str.append(" data = ["); Iterator i = iterator(); if(i.hasNext()) str.append(i.next()); while(i.hasNext()) { str.append(", "); str.append(i.next()); } str.append("]"); return str.toString(); }
public static void main(String[] args) { final RingBuffer ring = new RingBuffer(5);
final JTextField infoField = new JTextField(ring.bufferToString()); infoField.setEditable(false);
final JTextField pushField = new JTextField(); pushField.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ring.push(pushField.getText()); pushField.setText(""); infoField.setText(ring.bufferToString()); } }); JButton pushButton = new JButton("push"); pushButton.setFocusable(false); pushButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ring.push(pushField.getText()); pushField.setText(""); infoField.setText(ring.bufferToString()); } });
final JTextField popField = new JTextField(); popField.setEditable(false); JButton popButton = new JButton("pop"); popButton.setFocusable(false); popButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { popField.setText(String.valueOf(ring.pop())); } catch(EmptyRingBufferException ex) { popField.setText(ex.getMessage()); } infoField.setText(ring.bufferToString()); } });
final JSpinner spinner = new JSpinner(new SpinnerNumberModel(5 , 0 , 30 , 1)); spinner.setFocusable(false); JButton capacityButton = new JButton("Change capacity"); capacityButton.setFocusable(false); capacityButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ring.setCapacity( ( (Number) spinner.getValue()).intValue()); infoField.setText(ring.bufferToString()); } });
final JTextField getFirstField = new JTextField(); getFirstField.setEditable(false); JButton getFirstButton = new JButton("Get first"); getFirstButton.setFocusable(false); getFirstButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { getFirstField.setText(String.valueOf(ring.getFirst())); } catch(EmptyRingBufferException ex) { getFirstField.setText(ex.getMessage()); } infoField.setText(ring.bufferToString()); } });
final JTextField getLastField = new JTextField(); getLastField.setEditable(false); JButton getLastButton = new JButton("Get last"); getLastButton.setFocusable(false); getLastButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { try { getLastField.setText(String.valueOf(ring.getLast())); } catch(EmptyRingBufferException ex) { getLastField.setText(ex.getMessage()); } infoField.setText(ring.bufferToString()); } });
JPanel panel = new JPanel(new GridLayout(2 , 0)); panel.add(pushField); panel.add(popField); panel.add(spinner); panel.add(getFirstField); panel.add(getLastField); panel.add(pushButton); panel.add(popButton); panel.add(capacityButton); panel.add(getFirstButton); panel.add(getLastButton);
JFrame frame = new JFrame(); Container cont = frame.getContentPane(); cont.add(panel , BorderLayout.CENTER); cont.add(infoField , BorderLayout.SOUTH); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.pack(); frame.setLocationRelativeTo(null); frame.show(); } //*/
private class RingIterator implements Iterator { private int current;
public RingIterator() { current = start; }
public boolean hasNext() { if(start <= end) return current < end; else return( (current >= start) && (current < buffer.length)) || ( (current >= 0) && (current < end)); }
public Object next() { if(!hasNext()) throw new NoSuchElementException("RingBuffer has no more elemnts");
Object value = buffer[current];; if(start <= end) current++; else current = (current + 1) % buffer.length;
return value; }
public void remove() { throw new UnsupportedOperationException("RingBuffer does not support remove operation"); } } }
| Добавлено @ 23:38 Кстати это можно закинуть в FAQ по Collection Framework
--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
|