How to use generics that implements comparable - java-8

I am very confused about something in java. So the project I was given is write stacks in java, and the program begins with public class Stack<T extends Comparable<? super T>>. However, when trying to run it in my testing program, no matter the kind of Object I throw at it (Integer, String), it all return the error Ljava.lang.Object; cannot be cast to [Ljava.lang.Comparable. My question is how does this sort of generics that implement generic T but also extends Comparable work, and why String still returned the error message (I thought String already implemented Comparable<String>?). Thanks in advance for taking the time to read the question! Here is the rough outline of the code:
public class Stack <T extends Comparable<? super T>>{
private T[] arr;
private int ptr;
private int size;
public Stack(){
this.size = 20;
arr = (T[]) new Object[size];
ptr = -1;
}
public boolean push(T element){
try {
arr[ptr+1] = element;
ptr++;
return true;
}
catch (Exception e) {
return false;
}
}
public T[] toArray(){
return arr;
}
}
I got this error from creating a JUnit testing class, with the implementation of something like:
import static org.junit.Assert.assertEquals;
public class StackTester{
#Test
public void testPush(){
Stack<String> st = new Stack<String>();
for (int i = 0; i < 5; i++){
String var = new Integer(i).toString();
st.push(var);
}
assertEquals(new Integer[]{"3","4","5"}, st.toArray());
}
}
public class StackTester{
#Test
public void testPush(){
Stack<String> st = new Stack<String>();
//normal case
for (int i = 0; i < 5; i++){
String var = new Integer(i).toString();
st.push(var);
}
assertEquals(new Integer[]{3,4,5}, st.toArray());
}
}
Also, I have not added a compareTo method as I don't know what it should compare to, and I don't think there's a particular use case for adding that method. I should add that the goal of this project is to use stacks to manipulate Strings (such as going from infix to postfix).
P.S: I would also mention that I don't really need to compare stacks in my project, which is why the stack class itself is not implementing the Comparable interface.

Related

Sorting ArrayList of arraylist<integer>

I have the following ArrayList>. I need to sort this ArrayList by the size of arrayLists inside it. How can this be done?
Thank you!
Write Comparator for and use sort method :-
import java.util.*;
class ListComparator implements Comparator{
public int Compare(Object o1,Object o2){
ArrayList s1=(ArrayList)o1;
ArrayList s2=(ArrayList)o2;
if(s1.size()==s2.size())
return 0;
else if(s1.size()>s2.size())
return 1;
else
return -1;
}
}
Assuming you ArrayList is variable name myList.
Collections.sort(myList, new ListComparator());
Refer this link to understand the concept in java
import java.util.*;
class Details {
public static void main(String args[]){
ArrayList<Integer> listofcountries = new ArrayList<Integer>();
listofcountries.add(89);
listofcountries.add(5);
listofcountries.add(3);
listofcountries.add(9);
/*Unsorted List*/
System.out.println("Before Sorting:");
for(int counter: listofcountries){
System.out.println(counter);
}
/* Sort statement*/
Collections.sort(listofcountries);
/* Sorted List*/
System.out.println("After Sorting:");
for(int counter: listofcountries){
System.out.println(counter);
}
}
}``
Use this code work. This code Work Correct

Spliterator Java 8

I have a number from 1 to 10,000 stored in an array of long. When adding them sequentially it will give a result of 50,005,000.
I have writing an Spliterator where if a size of array is longer than 1000, it will be splitted to another array.
Here is my code. But when I run it, the result from addition is far greater than 50,005,000. Can someone tell me what is wrong with my code?
Thank you so much.
import java.util.Arrays;
import java.util.Optional;
import java.util.Spliterator;
import java.util.function.Consumer;
import java.util.stream.LongStream;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;
public class SumSpliterator implements Spliterator<Long> {
private final long[] numbers;
private int currentPosition = 0;
public SumSpliterator(long[] numbers) {
super();
this.numbers = numbers;
}
#Override
public boolean tryAdvance(Consumer<? super Long> action) {
action.accept(numbers[currentPosition++]);
return currentPosition < numbers.length;
}
#Override
public long estimateSize() {
return numbers.length - currentPosition;
}
#Override
public int characteristics() {
return SUBSIZED;
}
#Override
public Spliterator<Long> trySplit() {
int currentSize = numbers.length - currentPosition;
if( currentSize <= 1_000){
return null;
}else{
currentPosition = currentPosition + 1_000;
return new SumSpliterator(Arrays.copyOfRange(numbers, 1_000, numbers.length));
}
}
public static void main(String[] args) {
long[] twoThousandNumbers = LongStream.rangeClosed(1, 10_000).toArray();
Spliterator<Long> spliterator = new SumSpliterator(twoThousandNumbers);
Stream<Long> stream = StreamSupport.stream(spliterator, false);
System.out.println( sumValues(stream) );
}
private static long sumValues(Stream<Long> stream){
Optional<Long> optional = stream.reduce( ( t, u) -> t + u );
return optional.get() != null ? optional.get() : Long.valueOf(0);
}
}
I have the strong feeling that you didn’t get the purpose of splitting right. It’s not meant to copy the underlying data but just provide access to a range of it. Keep in mind that spliterators provide read-only access. So you should pass the original array to the new spliterator and configure it with an appropriate position and length instead of copying the array.
But besides the inefficiency of copying, the logic is obviously wrong: You pass Arrays.copyOfRange(numbers, 1_000, numbers.length) to the new spliterator, so the new spliterator contains the elements from position 1000 to the end of the array and you advance the current spliterator’s position by 1000, so the old spliterator covers the elements from currentPosition + 1_000 to the end of the array. So both spliterators will cover elements at the end of the array while at the same time, depending on the previous value of currentPosition, elements at the beginning might not be covered at all. So when you want to advance the currentPosition by 1_000 the skipped range is expressed by Arrays.copyOfRange(numbers, currentPosition, 1_000) instead, referring to the currentPosition before advancing.
It’s should also be noted, that a spliterator should attempt to split balanced, that is, in the middle if the size is known. So splitting off thousand elements is not the right strategy for an array.
Further, your tryAdvance method is wrong. It should not test after calling the consumer but before, returning false if there are no more elements, which also implies that the consumer has not been called.
Putting it all together, the implementation may look like
public class MyArraySpliterator implements Spliterator<Long> {
private final long[] numbers;
private int currentPosition, endPosition;
public MyArraySpliterator(long[] numbers) {
this(numbers, 0, numbers.length);
}
public MyArraySpliterator(long[] numbers, int start, int end) {
this.numbers = numbers;
currentPosition=start;
endPosition=end;
}
#Override
public boolean tryAdvance(Consumer<? super Long> action) {
if(currentPosition < endPosition) {
action.accept(numbers[currentPosition++]);
return true;
}
return false;
}
#Override
public long estimateSize() {
return endPosition - currentPosition;
}
#Override
public int characteristics() {
return ORDERED|NONNULL|SIZED|SUBSIZED;
}
#Override
public Spliterator<Long> trySplit() {
if(estimateSize()<=1000) return null;
int middle = (endPosition + currentPosition)>>>1;
MyArraySpliterator prefix
= new MyArraySpliterator(numbers, currentPosition, middle);
currentPosition=middle;
return prefix;
}
}
But of course, it’s recommended to provide a specialized forEachRemaining implementation, where possible:
#Override
public void forEachRemaining(Consumer<? super Long> action) {
int pos=currentPosition, end=endPosition;
currentPosition=end;
for(;pos<end; pos++) action.accept(numbers[pos]);
}
As a final note, for the task of summing longs from an array, a Spliterator.OfLong and a LongStream is preferred and that work has already been done, see Arrays.spliterator() and LongStream.sum(), making the whole task as simple as Arrays.stream(numbers).sum().

WTSEnumerateSessions from JNA

I'm trying to start a UI application from a java based Windows Service. If figured out so far, that the only approach to make this work is to get a list of sessions, find the one thats currently active, get the user handle for that session and finally create a new process for the given user.
I'm starting off by implementing the session enumeration using WTSEnumerateSessions, yet I'm struggling to get this working. The problem seems to be my mapping of the "_Out_ PWTS_SESSION_INFO *ppSessionInfo" parameter. I wrote the following code:
public interface Wtsapi32 extends StdCallLibrary {
Wtsapi32 INSTANCE = (Wtsapi32) Native.loadLibrary("Wtsapi32", Wtsapi32.class, W32APIOptions.DEFAULT_OPTIONS);
boolean WTSEnumerateSessions(IntByReference hServer, int Reserved, int Version, WTS_SESSION_INFO.ByReference[] ppSessionInfo, IntByReference pCount) throws LastErrorException;
class WTS_SESSION_INFO extends Structure {
public static class ByReference extends WTS_SESSION_INFO implements Structure.ByReference {}
public int sessionId;
public String pWinStationName;
public int state;
#Override
protected List getFieldOrder() {
return Arrays.asList("sessionId", "pWinStationName", "state");
}
}
}
On trying invoking the code with something like this:
public static void main(String[] argv) {
Wtsapi32.WTS_SESSION_INFO.ByReference[] sessionInfo = null;
IntByReference sessionCount = new IntByReference();
try {
if (Wtsapi32.INSTANCE.WTSEnumerateSessions(new IntByReference(0), 0, 1, sessionInfo, sessionCount)) {
System.out.println("success :-)");
}
} catch (LastErrorException ex) {
ex.printStackTrace();
}
}
I get a error code 1784 - ERROR_INVALID_USER_BUFFER. What would be the correct mapping for said API call from JNA?
Update:
I have tried a version suggested Remy Lebeau, but this gives me an Invalid memory access exception:
public interface Wtsapi32 extends StdCallLibrary {
Wtsapi32 INSTANCE = (Wtsapi32) Native.loadLibrary("Wtsapi32", Wtsapi32.class, W32APIOptions.DEFAULT_OPTIONS);
boolean WTSEnumerateSessions(IntByReference hServer, int Reserved, int Version, PointerByReference ppSessionInfo, IntByReference pCount) throws LastErrorException;
class WTS_SESSION_INFO extends Structure {
public static class ByReference extends WTS_SESSION_INFO implements Structure.ByReference {}
public int sessionId;
public String pWinStationName;
public int state;
#Override
protected List getFieldOrder() {
return Arrays.asList("sessionId", "pWinStationName", "state");
}
public WTS_SESSION_INFO() {}
public WTS_SESSION_INFO(Pointer p) {
super(p);
}
}
}
Main:
PointerByReference sessionInfoPtr = new PointerByReference();
IntByReference sessionCount = new IntByReference();
try {
if (Wtsapi32.INSTANCE.WTSEnumerateSessions(new IntByReference(0), 0, 1, sessionInfoPtr, sessionCount)) {
System.out.println("success :-)");
}
} catch (LastErrorException ex) {
ex.printStackTrace();
}
WTSEnumerateSessions() returns:
a pointer to an array of WTS_SESSION_INFO structures
a pointer to a DWORD of the number of elements in the the array.
So you need to pass a PointerByReference for the ppSessionInfo parameter, and a IntByReference for the pCount parameters. You can then use the values being pointed at by those pointers to access the array elements as needed. There is an example of this documented here:
JNA Example #7: Retrieve an Array of Structs from C
Also, your code is using an IntByReference for the hServer parameter. It needs to be a com.sun.jna.platform.win32.WinNT.HANDLE instead, or at least a Pointer. In C, a Win32 HANDLE is just a void* pointer. You need to set the first parameter to Pointer.NULL (which is what WTS_CURRENT_SERVER_HANDLE is defined as in C) to enumerate the sessions of the local server. IntByReference(0) is not the same thing as Pointer.NULL.
And don't forget to call WTSFreeMemory() to free the array data when you are done using it.
Try something like this:
public interface Wtsapi32 extends StdCallLibrary {
Wtsapi32 INSTANCE = (Wtsapi32) Native.loadLibrary("Wtsapi32", Wtsapi32.class, W32APIOptions.DEFAULT_OPTIONS);
boolean WTSEnumerateSessions(Pointer hServer, int Reserved, int Version, PointerByReference ppSessionInfo, IntByReference pCount) throws LastErrorException;
void WTSFreeMemory(Pointer pMemory);
class WTS_SESSION_INFO extends Structure {
public static class ByReference extends WTS_SESSION_INFO implements Structure.ByReference {}
public int sessionId;
public String pWinStationName;
public int state;
public WTS_SESSION_INFO() {}
public WTS_SESSION_INFO(Pointer p) {
super(p);
}
#Override
protected List getFieldOrder() {
return Arrays.asList("sessionId", "pWinStationName", "state");
}
}
}
public static void main(String[] argv) {
PointerByReference sessionInfoPtr = new PointerByReference();
IntByReference sessionCount = new IntByReference();
try {
if (Wtsapi32.INSTANCE.WTSEnumerateSessions(Pointer.NULL, 0, 1, sessionInfoPtr, sessionCount)) {
Pointer sessionInfo = sessionInfoPtr.getValue();
int count = sessionCount.getValue();
Wtsapi32.INSTANCE.WTS_SESSION_INFO arrRef = new Wtsapi32.INSTANCE.WTS_SESSION_INFO(sessionInfo);
arrRef.read(); // <-- not sure why this is here
Wtsapi32.INSTANCE.WTS_SESSION_INFO[] sessions = (Wtsapi32.INSTANCE.WTS_SESSION_INFO[])arrRef.toArray(count);
for (Wtsapi32.INSTANCE.WTS_SESSION_INFO session : sessions) {
// use session as needed...
}
WTSFreeMemory(sessionInfo);
}
} catch (LastErrorException ex) {
ex.printStackTrace();
}
}

Hadoop Raw comparator

I am trying to implement the following in a Raw Comparator but not sure how to write this?
the tumestamp field here is of tyoe LongWritable.
if (this.getNaturalKey().compareTo(o.getNaturalKey()) != 0) {
return this.getNaturalKey().compareTo(o.getNaturalKey());
} else if (this.timeStamp != o.timeStamp) {
return timeStamp.compareTo(o.timeStamp);
} else {
return 0;
}
I found a hint here, but not sure how do I implement this dealing with a LongWritabel type?
http://my.safaribooksonline.com/book/databases/hadoop/9780596521974/serialization/id3548156
Thanks for your help
Let say i have a CompositeKey that represents a pair of (String stockSymbol, long timestamp).
We can do a primary grouping pass on the stockSymbol field to get all of the data of one type together, and then our "secondary sort" during the shuffle phase uses the timestamp long member to sort the timeseries points so that they arrive at the reducer partitioned and in sorted order.
public class CompositeKey implements WritableComparable<CompositeKey> {
// natural key is (stockSymbol)
// composite key is a pair (stockSymbol, timestamp)
private String stockSymbol;
private long timestamp;
......//Getter setter omiited for clarity here
#Override
public void readFields(DataInput in) throws IOException {
this.stockSymbol = in.readUTF();
this.timestamp = in.readLong();
}
#Override
public void write(DataOutput out) throws IOException {
out.writeUTF(this.stockSymbol);
out.writeLong(this.timestamp);
}
#Override
public int compareTo(CompositeKey other) {
if (this.stockSymbol.compareTo(other.stockSymbol) != 0) {
return this.stockSymbol.compareTo(other.stockSymbol);
}
else if (this.timestamp != other.timestamp) {
return timestamp < other.timestamp ? -1 : 1;
}
else {
return 0;
}
}
Now the CompositeKey comparator would be:
public class CompositeKeyComparator extends WritableComparator {
protected CompositeKeyComparator() {
super(CompositeKey.class, true);
}
#Override
public int compare(WritableComparable wc1, WritableComparable wc2) {
CompositeKey ck1 = (CompositeKey) wc1;
CompositeKey ck2 = (CompositeKey) wc2;
int comparison = ck1.getStockSymbol().compareTo(ck2.getStockSymbol());
if (comparison == 0) {
// stock symbols are equal here
if (ck1.getTimestamp() == ck2.getTimestamp()) {
return 0;
}
else if (ck1.getTimestamp() < ck2.getTimestamp()) {
return -1;
}
else {
return 1;
}
}
else {
return comparison;
}
}
}
Are you asking about way to compare LongWritable type provided by hadoop ?
If yes, then the answer is to use compare() method. For more details, scroll down here.
The best way to correctly implement RawComparator is to extend WritableComparator and override compare() method. The WritableComparator is very good written, so you can easily understand it.
It is already implemented from what I see in the LongWritable class:
/** A Comparator optimized for LongWritable. */
public static class Comparator extends WritableComparator {
public Comparator() {
super(LongWritable.class);
}
public int compare(byte[] b1, int s1, int l1,
byte[] b2, int s2, int l2) {
long thisValue = readLong(b1, s1);
long thatValue = readLong(b2, s2);
return (thisValue<thatValue ? -1 : (thisValue==thatValue ? 0 : 1));
}
}
That byte comparision is the override of the RawComparator.

Accessing class variables from private actionPerformed method

In the code below, I don't know why the values of variables uNomba and list are NULL when accessed from jButton1ActionPerformed method. I would appreciate your help, on how I can successfully execute "new NewPlayer(uNomba, count, check, list).load();" such that all the values are passed to NewPlayer class. Thank you.
The first class - i.e The NewPlayer class
package mysound;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class NewPlayer extends JPanel implements KeyListener, Runnable{
boolean isUpPressed, isDownPressed, isSpacePressed, isDone;
static JFrame f;
int spacebars=0;
boolean within;
public List spacebarLogMs = new ArrayList();
public List numSbar = new ArrayList();
Calendar cal = Calendar.getInstance();
LogResult logNow = new LogResult();
String directory;
String tabname; //table name used in the database connection
String bdir;
private int uNomba; //user number obtained from NewSound class
private String target;
private int incr;
private int userno;
private boolean moveon=true;
private List randlist;
private List numlist;
public void load() {
f = new JFrame();
f.setSize(600,300);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setContentPane(this);
f.setVisible(true);
setFocusable(true);
addKeyListener(this);
new Thread(this).start();
}
public NewPlayer() {
}
public NewPlayer(int UNOMBA, List NUMLIST){
this.uNomba = UNOMBA; //user number obtained from NewSound class
this.numlist=NUMLIST;
}
public NewPlayer(int USERNO, int INCR, boolean MOVEON, List NUMLIST){
this.userno=USERNO;
this.incr=INCR;
this.moveon=MOVEON;
this.numlist=NUMLIST;
}
public void keyTyped(KeyEvent ke) {
}
public void keyPressed(KeyEvent ke) {
switch(ke.getKeyCode()) {
case KeyEvent.VK_UP: isUpPressed = true; break;
case KeyEvent.VK_DOWN: isDownPressed = true; break;
case KeyEvent.VK_SPACE: isSpacePressed = true;
numSbar.add(System.currentTimeMillis());
System.out.println("That was a spacebar. "+spacebars++);
System.out.println("Current time: "+numSbar);
break;
}
}
public void keyReleased(KeyEvent ke) {
switch(ke.getKeyCode()) {
case KeyEvent.VK_UP: isUpPressed = false; break;
case KeyEvent.VK_DOWN: isDownPressed = false; break;
case KeyEvent.VK_SPACE: isSpacePressed = false; break;
}
}
public void closePrj(){
f.dispose();
}
public void run() { //introduce a target sound
String targetChoice;
int tIndex;
int i;
bdir="C:\\Users\\Abiodun\\Desktop\\testdata\\main\\zero\\atext\\"; //dir for text files
MainPlayer items = new MainPlayer (uNomba);
i=incr;
while(moveon){
System.out.println("Counter i: "+i+" Numlist: "+numlist);
if (i<numlist.size()){
int num = (int) numlist.get(i);
System.out.println("Num :"+num);
items.selectTarget(num);
items.selectChallenge(num);
items.playChallenge();
new WriteTime(bdir).tagTime(numSbar);
items.dataLogger();
moveon=false;
new Continue (uNomba, i, moveon, numlist).load();
}
}
}
}
The second class i.e the Continue class
public class Continue extends javax.swing.JDialog {
private int count;
private int usernumb;
private boolean check;
private int uNomba;
private String cdirectory;
private String cbdir;
private String ctabname;
private String ctarget;
private List list;
/**
* Creates new form Continue
*/
public Continue(java.awt.Frame parent, boolean modal) {
super(parent, modal);
initComponents();
}
public Continue(int CUNOMBA, int COUNT, boolean CHECK, List NLIST){
this.uNomba = CUNOMBA; //user number obtained from NewSound class
this.count=COUNT;
this.check=CHECK;
this.list=NLIST;
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
new NewPlayer().setVisible(false);//closePrj();
count++;
check=true;
new NewPlayer(uNomba, count, check, list).load();
System.out.println("Continue: UserNumber: "+uNumb+", Count: "+count+", Check: "+check+", nList"+lst);
this.setVisible(false);
}
Thanks sgroh. Here is what I just added: I created the following in
In NewPlayer class:
Continue ct = new Continue (new NewPlayer(uNomba, i, moveon, numlist));
In Continue Class,
private NewPlayer np;
public Continue (NewPlayer npy){
this.npy=np;
}
Just a recap, the main problem I am having is that I cannot access the values I passed from NewPlayer class from Continue class. I tested the values in side the following constructor in Continue class but not anywhere else in Continue class.
public Continue(int CUNOMBA, int COUNT, boolean CHECK, List NLIST){
this.uNomba = CUNOMBA; //user number obtained from NewSound class
this.count=COUNT;
this.check=CHECK;
this.nlist=NLIST;
System.out.println("Continue-constructor - uNomba: "+uNomba+", nList: "+list); //works fine! but not outside this constructor.
}
This code even compile, You haven't a constructor default (without fields).
this:
public Continue(java.awt.Frame parent, boolean modal) {
and This:
public Continue(int CUNOMBA, int COUNT, boolean CHECK, List NLIST){
this woun't compile:
Continue ctn = new Continue();
You have to create the Continue object using the right constructor or create the Default constructor.
You want also to print the variable uNumb in the System.out.println that doesn't exists.

Resources