I have a public method (called getMusic) in a class called Favorites. getMusic has set. There are 3 sets and in each set has five words, Set getMusic(). In another class called myInterest, there is a treeSet called musicTable. I called getMusic method into myInterest class but I do not know how to iterate over so that the set of words can be added to musicTable TreeSet. I tried to use addAll but it's not working. Where I am going wrong and how do I fix this? .I don't want to use list, I've thought about for loop but not to sure how to use this or literate(). thank you
public class myInterest
{
private static TreeSet<String> musicTable = new TreeSet<String>();
public Test()
{
super();
musicTable = new TreeSet<String>();
}
public static void testOut()
{
Favorites entrainment = new Favorites();
System.out.println(" " + entrainment.getMusic());
entrainment.addAll(musicTable); //error msg "cannot find symbol - method addAll(java.util.TreeSet<java.lang.String>)
musicTable.addAll(entrainment); //also tried this way but error msg "cannot find symbol - method addAll(Favorities)
}
}
Do you mean:
musicTable.addAll(entrainment.getMusic());
?
Related
In Java we can not reassign a reference inside a method.
So the following does not work:
class SomeClass {
List<PaidOrders> paidOrders;
List<PendingOrders> pendingOrders;
List<CancelledOrders> cancelledOrders;
private void process(List<OrderStatus> data, List<Orders> currentOrderlist) {
List<Order> newOrders = fromOrderStatus(data);
currentOrderlist = newOrders;
}
}
But the following does work:
class SomeClass {
private void process(List<OrderStatus> data, List<Orders> currentOrderlist) {
List<Order> newOrders = fromOrderStatus(data);
currentOrderlist.clear();
currentOrderlist.addAll(newOrders); // <- extra linear loop
}
}
The problem is that the second example does an extra linear loop to copy from one list to the other.
Question:
I was wondering, is there some design approach so that I could neatly just replace the references instead? I.e. somehow make the first snippet work with some change in the parameters or something?
Update
After the comments I would like to clarify that the currentOrderList can be any of the paidOrders, pendingOrders, cancelledOrders.
The code for process is the same for all types.
Hm. I see two possibilities here. Either you use some wrapper object such as AtomicReference (might be a bit overpowered because of the multi-threading issues) as the argument and then just set it there or you use a consumer.
In the second case your method would look like this:
public void process(List<OrderStatus> data, Consumer<List<Orders>> target) {
List<Person> newOrders = fromOrderStatus(data);
target.accept(newOrders);
}
Then on the calling side you would implement it like this:
process(data, e-> <<targetList>> = e);
If your list will be wrapped by a different object (for example - AtomicReference), then you will be able to change it.
public static void doSomething(AtomicReference<List<Integer>> listAtomicReference){
List<Integer> newIntegers = new ArrayList<>();
listAtomicReference.set(newIntegers);
}
public static void main(String[] args) {
AtomicReference<List<Integer>> listAtomicReference = new AtomicReference<>(Arrays.asList(4));
doSomething(listAtomicReference);
System.out.println(listAtomicReference.get());
}
Output:
[]
Making a public member variable in a class.
With that being said, I wouldn't recommend walking this path.
Is premature optimization really the root of all evil?
I've looked on here and what i got did not really work. Here is the code which runs but it's not doing what i expect it to do
package bcu.gui;
import java.util.ArrayList;
import java.util.Arrays;
public class compare {
private static ArrayList<String> list = new ArrayList<String>();
public static void main(String[] args) {
list.add("Paul");
list.add("James");
System.out.println(list); // Printing out the list
// If the list containsthe name Paul, then print this. It still doesn't print even though paul is in the list
if(Arrays.asList(list).contains("Paul")){
System.out.println("Yes it does");
}
}
}
you don't have to do this:
if(Arrays.asList(list).contains("Paul"))
because the identifier list is already an ArrayList
you'll need to do:
if(list.contains("Paul")){
System.out.println("Yes it does");
}
The reason why you not getting what you expected is the usage of
Arrays.asList(list)
which returns a new array with a single element of type array. If your list contains two elements [Paul, James], then the Arrays.asList(list) will be
[[Paul, James]].
The correct solution for the problem already provided by 'Ousmane Mahy Diaw'
The following will also work for you:
// if you want to create a list in one line
if (Arrays.asList("Paul", "James").contains("Paul")) {
System.out.println("Yes it does");
}
// or if you want to use a copy of you list
if (new ArrayList<>(list).contains("Paul")) {
System.out.println("Yes it does");
}
ArrayList have their inbuilt function called contains(). So if you want to try with in built function you can simply use this method.
list.contains("Your_String")
This will return you boolean value true or false
I'm calling a method like this:
final List<TimeCard> timeCards = new ArrayList<TimeCard>();
ListFactory.populateLists(accounts, consultants, timeCards);
...
TimeCardListUtil.sortByStartDate(timeCards);
System.out.println("Time cards by date:");
for (TimeCard tc : timeCards) {
System.out.printf(" %s, %s%n", tc.getWeekStartingDay(), tc.getConsultant());
}
And here is the method declaration:
public static void sortByStartDate(List<TimeCard> timeCards){
timeCards.stream().sorted((e1, e2) -> e1.getWeekStartingDay().compareTo(e2.getWeekStartingDay())).forEach(e -> System.out.println(e));
}
The println in the method declaration prints the correct order, but if I print the list from the calling class, the order is unchanged.
Please help. I haven't been able to find solutions because I possibly don't know how to phrase the question.
Thanks in advance!
You have sorted the stream, NOT THE List<TimeCard> which is passed in.
Assign back the timeCards variable within the sortByStartDate method. You will get the change reflected outside the method.
use collet() in order to do this.
public static void sortByStartDate(List<TimeCard> timeCards){
timeCards = timeCards.stream()
.sorted((e1, e2) -> e1.getWeekStartingDay().compareTo(e2.getWeekStartingDay())).collect(Collectors.toList());
}
Alternative clean way is:
timeCards.sort((e1, e2) -> e1.getWeekStartingDay().compareTo(e2.getWeekStartingDay()));
Update:
You can simplify the sorting by without passing the lambda, but get the advantage of method references with the Comparator class.
public static void sortByStartDate(List<TimeCard> timeCards){
timeCards = timeCards.stream()
.sort(Comparator.comparing(TimeCard::getWeekStartingDay)).collect(Collectors.toList());
}
The sorted() function doesn't change the stream that it operates on. You need to make your function return the result of the sorted() function.
I'm not sure if this is a duplicat or not (it probably is) but I can't find what I'm looking for.
I have a static ArrayList holding objects created from a constructor in that class, or any class extending it:
public static ArrayList<Person> PersonList = new ArrayList<>();
public Constructor(....){
PersonList.add(this);
}
Now I'm trying to delete objects from this arraylist by using index, but I'm getting ArrayIndexOutOfBounds: Array index out of range: (index).
Now I know this error is telling me there is no element in the specified position, but then I don't understand why PersonList.size() returns 4 (if there are 4 elements in the list).
I'm new to java, so I hope anyone here can help me. Here's the code:
list.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent arg0) {
if(SwingUtilities.isRightMouseButton(arg0)) {
try {
Person.PersonList.remove(list.getSelectedIndex());
list.remove(list.getSelectedIndex());
}catch (Exception e) {
System.out.println(e);
}
System.out.println("Index: " + list.getSelectedIndex());
updateData();
}
}
});
I'm confused by this:
public Constructor(....){
PersonList.add(this);
}
It looks like every time you create a new object of that class (a Person I'm assuming) you are adding it to a class variable list. I'm assuming that every time you create a new instance of that class, it's resetting the global list. Can you confirm that PersonList is not always size = 1? I'm suspecting it is, so move that list to a different class
Okay so after testing a little it seems it works just fine after all. It throws an error telling me its out of bounds, but after updating the .size() after each deletion, it decreases.
Though I have no clue why it works if it tells me it doesn't?
This might seem like a pretty detailed question about Easymock, but I'm having a hard time finding a support site/forum/mailing list for this library.
I'm encountering a bug when using the captures() method that seems to return the captured parameters out of order.
Here's a simplified version of what I am testing:
public class CaptureTest extends TestCase {
// interface we will be mocking
interface Processor {
void process(String x);
}
// class that uses the interface above which will receive the mock
class Component {
private Processor processor;
private String[] s = { "one", "two", "three", "four" };
Component(Processor processor) {
this.processor = processor;
}
public void doSomething() {
for (int i = 0; i < s.length; i++) {
processor.process(s[i]);
}
}
}
public void testCapture() {
//create the mock, wire it up
Processor mockProcessor = createMock(Processor.class);
Component component = new Component(mockProcessor);
//we're going to call the process method four times
//with different arguments, and we want to capture
//the value passed to the mock so we can assert against it later
Capture<String> cap1 = new Capture<String>();
Capture<String> cap2 = new Capture<String>();
Capture<String> cap3 = new Capture<String>();
Capture<String> cap4 = new Capture<String>();
mockProcessor.process(and(isA(String.class), capture(cap1)));
mockProcessor.process(and(isA(String.class), capture(cap2)));
mockProcessor.process(and(isA(String.class), capture(cap3)));
mockProcessor.process(and(isA(String.class), capture(cap4)));
replay(mockProcessor);
component.doSomething();
//check what values were passed to the mock
assertEquals("one", cap1.getValue());
assertEquals("two", cap2.getValue());
assertEquals("three", cap3.getValue());
assertEquals("four", cap4.getValue());
verify(mockProcessor);
}
}
(Please note that this is just a simplified test case - I know that I could specify the exact value of the arguments I expect passed to my mock, but in my real case the arguments are complex objects with a handful of fields, and I want to capture the object so I can assert against just a few of those fields without re-creating the entire object in my test case).
When I run the test, it fails at:
junit.framework.ComparisonFailure: expected:<[one]> but was:<[four]>
Meaning that the parameter that EasyMock is capturing in cap1 is not the first call to the method, but the last (since the value is four). I get the same results if I reverse the captures() declarations, i.e. use cap4 with the first method call, etc.
This seems like it might be a bug within EasyMock - different parameters passed to the same method in different invocations don't seem to be capture correctly.
Is anyone else using capture() with EasyMock and having similar problems? Is there an easy workaround you know of, or a different way I can capture the parameters being passed to my mock's methods?
Update 1: fixed code sample to show I am using createMock, not createStrictMock, but I get the same error with both (although the actual value of what is captured changes).
I've received an answer on the bug I submitted to the Easymock sourceforge site, and a developer has confirmed it is indeed a bug with this version of Easymock.
It is indeed a bug. The capture is done even if it was already done. The
current workaround is to implement your own capture object and override
setValue to do this:
#Override
public void setValue(T value) {
if(!hasCaptured()) {
super.setValue(value);
}
}
I was playing around with your test and could not solve.
However I extended the Capture Class to see if the values were set in a different order (I was suspicious that EasyMock internally was using a hash with a key generated from the methods and the parameters) I was wrong the methods are set in the correct order. But there is something really weird going on.. It seems that the algorithm does some kind assigning pattern.. Well let me show the code and the strange output.... BTW the changes from mock, niceMock and strictMock didn't make anydifference..
class MyCapture extends Capture<String> {
private String id;
public MyCapture(String id) {
super();
System.out.printf("Constructor %s expecting %s\n", id, this.getClass().getName());
this.id = id;
}
private static final long serialVersionUID = 1540983654657997692L;
#Override
public void setValue(String value) {
System.out.printf("setting value %s expecting %s \n", value, id);
super.setValue(value);
}
#Override
public String getValue() {
System.out
.printf("getting value %s expecting %s \n", super.getValue(), id);
return super.getValue();
}
}
public void testCapture() {
// create the mock, wire it up
Processor mockProcessor = createStrictMock(Processor.class);
Component component = new Component(mockProcessor);
// we're going to call the process method four times
// with different arguments, and we want to capture
// the value passed to the mock so we can assert against it later
Capture<String> cap1 = new MyCapture("A");
Capture<String> cap2 = new MyCapture("B");
Capture<String> cap3 = new MyCapture("C");
Capture<String> cap4 = new MyCapture("D");
mockProcessor.process(and(isA(String.class), capture(cap1)));
mockProcessor.process(and(isA(String.class), capture(cap2)));
mockProcessor.process(and(isA(String.class), capture(cap3)));
mockProcessor.process(and(isA(String.class), capture(cap4)));
replay(mockProcessor);
component.doSomething();
// check what values were passed to the mock
assertEquals("A", cap1.getValue());
assertEquals("B", cap2.getValue());
assertEquals("C", cap3.getValue());
assertEquals("D", cap4.getValue());
verify(mockProcessor);
}
}
*And this is the output *
Constructor A expecting com.comp.core.dao.impl.CaptureTest$MyCapture
Constructor B expecting com.comp.core.dao.impl.CaptureTest$MyCapture
Constructor C expecting com.comp.core.dao.impl.CaptureTest$MyCapture
Constructor D expecting com.comp.core.dao.impl.CaptureTest$MyCapture
calling process A
setting value A expecting A
calling process B
setting value B expecting A <<Setting the wrong guy
setting value B expecting A <<Setting the wrong guy
setting value B expecting B <<Ops this is the right one..stop
calling process C
setting value C expecting B <<Setting the wrong guy
setting value C expecting B <<Setting the wrong guy
setting value C expecting C <<Setting the wrong guy
calling process D
setting value D expecting C <<Setting the wrong guy
setting value D expecting C <<Setting the wrong guy
setting value D expecting D <<Ops this is the right one..stop
getting value B expecting A
Sorry I can't help you more. It might be indeed a bug in easy mock.
You can also try using EasyMock.createNiceMock(...) instead of EasyMock.createStrictMock(...) or EasyMock.createMock(...).
Although, I agree that it looks more like a bug with createMock.
This is a problem more appropriate for state-based testing, I think.
With JMockit, you could solve it like this:
import mockit.*;
import static mockit.Mockit.*;
import mockit.integration.junit3.*;
public class CaptureTest extends JMockitTestCase
{
interface Processor { void process(String x); }
class Component
{
private final Processor processor;
private final String[] s = {"one", "two", "three", "four"};
Component(Processor processor) { this.processor = processor; }
public void doSomething()
{
for (String value : s) {
processor.process(value);
}
}
}
#MockClass(realClass = Processor.class)
static class MockProcessor
{
private final String[] expectedValues;
private int i;
MockProcessor(String... expectedValues) { this.expectedValues = expectedValues; }
#Mock
void process(String x)
{
assertEquals(expectedValues[i++], x);
}
}
public void testCapture()
{
Processor mockProcessor = setUpMock(new MockProcessor("one", "two", "three", "four"));
Component component = new Component(mockProcessor);
component.doSomething();
}
}
In short, here's what worked for me:
MyClass myMock = EasyMock.createStrictMock(MyClass.class);
...
EasyMock.checkOrder(myMock, true); // before the capture and verify, not sure if it matters
...
Capture<MyArg> capturedArgs = new Capture<MyArg>();
expect(myMock.search(capture(capturedArgs))).andReturn(someRandomReturn);
PS: I'm using EasyMock 3.0
Instead of calling EasyMock.createStrictMock(...) just call EasyMock.createMock(...). Should solve your problems.